Bagaimana cara menyalin file dari folder 'aset' ke sdcard?
251
Saya punya beberapa file di assetsfolder. Saya perlu menyalin semuanya ke folder say / sdcard / folder. Saya ingin melakukan ini dari dalam utas. Bagaimana saya melakukannya?
Sebelum Anda menyalin / menempelkan salah satu (luar biasa) solusi di bawah ini, pertimbangkan untuk menggunakan perpustakaan ini untuk melakukannya dalam satu baris kode: stackoverflow.com/a/41970539/9648
JohnnyLambada
Jawaban:
346
Jika ada orang lain yang memiliki masalah yang sama, ini adalah bagaimana saya melakukannya
untuk menulis file di sdcard Anda harus memberikan izin pada manifes misalnya <menggunakan-izin android: name = "android.permission.WRITE_EXTERNAL_STORAGE" />
IronBlossom
22
Saya juga tidak akan bergantung pada sdcard yang berada di / sdcard, tetapi mengambil lintasan dengan Environment.getExternalStorageDirectory ()
Axarydax
2
Haruskah saya gunakan: 16 * 1024 (16kb) Saya cenderung memilih 16K atau 32K sebagai keseimbangan yang baik antara penggunaan memori dan kinerja.
Nam Vu
3
@rciovati mendapat kesalahan runtime iniFailed to copy asset file: myfile.txt java.io.FileNotFoundException: myfile.txt at android.content.res.AssetManager.openAsset(Native Method)
likejudo
7
Bagi saya kode ini hanya berfungsi jika saya menambahkan ini: di in = assetManager.open("images-wall/"+filename);mana "gambar-dinding" adalah folder di dalam aset saya
Ultimo_m
62
Berdasarkan solusi Anda, saya melakukan sesuatu sendiri untuk memungkinkan subfolder. Seseorang mungkin menganggap ini bermanfaat:
assetManager.list(path)mungkin lambat di perangkat, untuk membuat daftar jalur aset sebelumnya cuplikan ini dapat digunakan dari assetsdir:find . -name "*" -type f -exec ls -l {} \; | awk '{print substr($9,3)}' >> assets.list
alexkasko
3
Solusi bagus! Satu-satunya perbaikan yang diperlukan adalah memotong pemisah utama di awal copyFileOrDir (): path = path.startsWith ("/")? path.substring (1): path;
Cross_
Alur
2
ganti "/ data / data /" + this.getPackageName () dengan this.getFilesDir (). getAbsolutePath ()
ibrahimyilmaz
1
... dan tutup stream di finallyblok))
Mixaz
48
Solusi di atas tidak berfungsi karena beberapa kesalahan:
pembuatan direktori tidak berfungsi
aset yang dikembalikan oleh Android juga mengandung tiga folder: gambar, suara, dan webkit
Cara yang ditambahkan untuk menangani file besar: Tambahkan ekstensi .mp3 ke file dalam folder aset di proyek Anda dan selama menyalin file target akan tanpa ekstensi .mp3
Ini kodenya (saya meninggalkan pernyataan Log tetapi Anda dapat menjatuhkannya sekarang):
finalstaticString TARGET_BASE_PATH ="/sdcard/appname/voices/";privatevoid copyFilesToSdCard(){
copyFileOrDir("");// copy all files in assets folder in my project}privatevoid copyFileOrDir(String path){AssetManager assetManager =this.getAssets();String assets[]=null;try{Log.i("tag","copyFileOrDir() "+path);
assets = assetManager.list(path);if(assets.length ==0){
copyFile(path);}else{String fullPath = TARGET_BASE_PATH + path;Log.i("tag","path="+fullPath);File dir =newFile(fullPath);if(!dir.exists()&&!path.startsWith("images")&&!path.startsWith("sounds")&&!path.startsWith("webkit"))if(!dir.mkdirs())Log.i("tag","could not create dir "+fullPath);for(int i =0; i < assets.length;++i){String p;if(path.equals(""))
p ="";else
p = path +"/";if(!path.startsWith("images")&&!path.startsWith("sounds")&&!path.startsWith("webkit"))
copyFileOrDir( p + assets[i]);}}}catch(IOException ex){Log.e("tag","I/O Exception", ex);}}privatevoid copyFile(String filename){AssetManager assetManager =this.getAssets();InputStreamin=null;OutputStreamout=null;String newFileName =null;try{Log.i("tag","copyFile() "+filename);in= assetManager.open(filename);if(filename.endsWith(".jpg"))// extension was added to avoid compression on APK file
newFileName = TARGET_BASE_PATH + filename.substring(0, filename.length()-4);else
newFileName = TARGET_BASE_PATH + filename;out=newFileOutputStream(newFileName);byte[] buffer =newbyte[1024];int read;while((read =in.read(buffer))!=-1){out.write(buffer,0, read);}in.close();in=null;out.flush();out.close();out=null;}catch(Exception e){Log.e("tag","Exception in copyFile() of "+newFileName);Log.e("tag","Exception in copyFile() "+e.toString());}}
EDIT: Mengoreksi tempat yang salah ";" yang melemparkan kesalahan sistematis "tidak dapat membuat dir".
CATATAN: Log.i ("tag", "tidak dapat membuat dir" + fullPath); selalu terjadi sebagai; salah tempat pada if.
RoundSparrow hilltx
cara awsome! Terima kasih banyak! Tapi mengapa Anda memeriksa file jpg?
Phuong
32
Saya tahu ini telah dijawab tetapi saya memiliki cara yang sedikit lebih elegan untuk menyalin dari direktori aset ke file di sdcard. Ini tidak memerlukan loop "for" tetapi sebaliknya menggunakan File Streams dan Channels untuk melakukan pekerjaan.
(Catatan) Jika menggunakan semua jenis file terkompresi, APK, PDF, ... Anda mungkin ingin mengubah nama ekstensi file sebelum memasukkan ke dalam aset dan kemudian mengganti nama setelah Anda menyalinnya ke SDcard)
AssetManager am = context.getAssets();AssetFileDescriptor afd =null;try{
afd = am.openFd("MyFile.dat");// Create new file to copy into.File file =newFile(Environment.getExternalStorageDirectory()+ java.io.File.separator +"NewFile.dat");
file.createNewFile();
copyFdToFile(afd.getFileDescriptor(), file);}catch(IOException e){
e.printStackTrace();}
Cara untuk menyalin file tanpa harus mengulanginya.
Menyukai ini di atas solusi lain, sedikit lebih rapi. Modifikasi sedikit pada saya yang termasuk membuat fileFolders hilang. Bersulang!
Chris. Jenkins
3
Ini tidak akan berhasil melewati deskriptor file untuk saya, This file can not be opened as a file descriptor; it is probably compressed- ini adalah file pdf. Tahu cara memperbaikinya?
Gaʀʀʏ
1
Ini mengasumsikan bahwa inChannel.size () mengembalikan ukuran ukuran file. Tidak ada jaminan seperti itu . Saya mendapatkan 2,5 MiB untuk 2 file masing-masing 450 KiB.
AI0867
1
Saya baru saja menemukan bahwa AssetFileDescriptor.getLength () akan mengembalikan filesize yang benar.
AI0867
1
Selain hal di atas, aset tidak boleh dimulai di lokasi 0 di deskriptor file. AssetFileDescriptor.getStartOffset () akan mengembalikan offset awal.
AI0867
5
coba ini lebih sederhana, ini akan membantu Anda:
// Open your local db as the input streamInputStream myInput = _context.getAssets().open(YOUR FILE NAME);// Path to the just created empty dbString outFileName =SDCARD PATH + YOUR FILE NAME;// Open the empty db as the output streamOutputStream myOutput =newFileOutputStream(outFileName);// transfer bytes from the inputfile to the outputfilebyte[] buffer =newbyte[1024];int length;while((length = myInput.read(buffer))>0){
myOutput.write(buffer,0, length);}// Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
daftar (assetPath) ?. biarkan {...} sebenarnya. Nullable.
Gábor
4
Ini adalah versi yang dibersihkan untuk perangkat Android saat ini, desain metode fungsional sehingga Anda dapat menyalinnya ke kelas AssetsHelper misalnya;)
/**
*
* Info: prior to Android 2.3, any compressed asset file with an
* uncompressed size of over 1 MB cannot be read from the APK. So this
* should only be used if the device has android 2.3 or later running!
*
* @param c
* @param targetFolder
* e.g. {@link Environment#getExternalStorageDirectory()}
* @throws Exception
*/@TargetApi(Build.VERSION_CODES.GINGERBREAD)publicstaticboolean copyAssets(AssetManager assetManager,File targetFolder)throwsException{Log.i(LOG_TAG,"Copying files from assets to folder "+ targetFolder);return copyAssets(assetManager,"", targetFolder);}/**
* The files will be copied at the location targetFolder+path so if you
* enter path="abc" and targetfolder="sdcard" the files will be located in
* "sdcard/abc"
*
* @param assetManager
* @param path
* @param targetFolder
* @return
* @throws Exception
*/publicstaticboolean copyAssets(AssetManager assetManager,String path,File targetFolder)throwsException{Log.i(LOG_TAG,"Copying "+ path +" to "+ targetFolder);String sources[]= assetManager.list(path);if(sources.length ==0){// its not a folder, so its a file:
copyAssetFileToFolder(assetManager, path, targetFolder);}else{// its a folder:if(path.startsWith("images")|| path.startsWith("sounds")|| path.startsWith("webkit")){Log.i(LOG_TAG," > Skipping "+ path);returnfalse;}File targetDir =newFile(targetFolder, path);
targetDir.mkdirs();for(String source : sources){String fullSourcePath = path.equals("")? source :(path
+File.separator + source);
copyAssets(assetManager, fullSourcePath, targetFolder);}}returntrue;}privatestaticvoid copyAssetFileToFolder(AssetManager assetManager,String fullAssetPath,File targetBasePath)throwsIOException{InputStreamin= assetManager.open(fullAssetPath);OutputStreamout=newFileOutputStream(newFile(targetBasePath,
fullAssetPath));byte[] buffer =newbyte[16*1024];int read;while((read =in.read(buffer))!=-1){out.write(buffer,0, read);}in.close();out.flush();out.close();}
Menggunakan beberapa konsep dalam jawaban untuk pertanyaan ini, saya menulis sebuah kelas yang disebut AssetCopieruntuk membuat penyalinan menjadi /assets/sederhana. Ini tersedia di github dan dapat diakses dengan jitpack.io :
Pertama, Anda perlu memastikan bahwa file tersebut disimpan tanpa terkompresi. Sistem pengemasan dapat memilih untuk mengompres file apa pun dengan ekstensi yang tidak ditandai sebagai noCompress , dan file yang dikompresi tidak dapat dipetakan dalam memori, jadi Anda harus mengandalkan AssetManager.open dalam kasus itu.
Anda dapat menambahkan ekstensi '.mp3' ke file Anda untuk menghentikannya agar tidak dikompres, tetapi solusi yang tepat adalah dengan memodifikasi file app / build.gradle Anda dan menambahkan baris berikut (untuk menonaktifkan kompresi file PDF)
aaptOptions {
noCompress 'pdf'}
Pengepakan file
Perhatikan bahwa pembuat paket masih dapat mengemas beberapa file menjadi satu, jadi Anda tidak bisa hanya membaca seluruh file yang diberikan AssetManager kepada Anda. Anda perlu bertanya pada AssetFileDescriptor bagian mana yang Anda butuhkan.
Menemukan bagian yang benar dari file yang dikemas
Setelah Anda memastikan file Anda disimpan tanpa kompresi, Anda dapat menggunakan metode AssetManager.openFd untuk mendapatkan AssetFileDescriptor , yang dapat digunakan untuk mendapatkan FileInputStream (tidak seperti AssetManager.open , yang mengembalikan InputStream ) yang berisi FileChannel . Ini juga berisi offset awal (getStartOffset) dan ukuran (getLength) , yang Anda perlukan untuk mendapatkan bagian file yang benar.
Hai teman-teman, saya melakukan sesuatu seperti ini. Untuk Nth thth Copy Folder dan Files untuk menyalin. Yang Memungkinkan Anda untuk menyalin semua struktur direktori untuk disalin dari Android AssetManager :)
privatevoid manageAssetFolderToSDcard(){try{String arg_assetDir = getApplicationContext().getPackageName();String arg_destinationDir =FRConstants.ANDROID_DATA + arg_assetDir;FileFolderInCache=newFile(arg_destinationDir);if(!FolderInCache.exists()){
copyDirorfileFromAssetManager(arg_assetDir, arg_destinationDir);}}catch(IOException e1){
e1.printStackTrace();}}publicString copyDirorfileFromAssetManager(String arg_assetDir,String arg_destinationDir)throwsIOException{File sd_path =Environment.getExternalStorageDirectory();String dest_dir_path = sd_path + addLeadingSlash(arg_destinationDir);File dest_dir =newFile(dest_dir_path);
createDir(dest_dir);AssetManager asset_manager = getApplicationContext().getAssets();String[] files = asset_manager.list(arg_assetDir);for(int i =0; i < files.length; i++){String abs_asset_file_path = addTrailingSlash(arg_assetDir)+ files[i];String sub_files[]= asset_manager.list(abs_asset_file_path);if(sub_files.length ==0){// It is a fileString dest_file_path = addTrailingSlash(dest_dir_path)+ files[i];
copyAssetFile(abs_asset_file_path, dest_file_path);}else{// It is a sub directory
copyDirorfileFromAssetManager(abs_asset_file_path, addTrailingSlash(arg_destinationDir)+ files[i]);}}return dest_dir_path;}publicvoid copyAssetFile(String assetFilePath,String destinationFilePath)throwsIOException{InputStreamin= getApplicationContext().getAssets().open(assetFilePath);OutputStreamout=newFileOutputStream(destinationFilePath);byte[] buf =newbyte[1024];int len;while((len =in.read(buf))>0)out.write(buf,0, len);in.close();out.close();}publicString addTrailingSlash(String path){if(path.charAt(path.length()-1)!='/'){
path +="/";}return path;}publicString addLeadingSlash(String path){if(path.charAt(0)!='/'){
path ="/"+ path;}return path;}publicvoid createDir(File dir)throwsIOException{if(dir.exists()){if(!dir.isDirectory()){thrownewIOException("Can't create directory, a file is in the way");}}else{
dir.mkdirs();if(!dir.isDirectory()){thrownewIOException("Unable to create directory");}}}
Berdasarkan solusi Rohith Nandakumar, saya melakukan sesuatu sendiri untuk menyalin file dari subfolder aset (yaitu "aset / MyFolder "). Juga, saya memeriksa apakah file sudah ada di sdcard sebelum mencoba menyalin lagi.
privatevoid copyAssets(){AssetManager assetManager = getAssets();String[] files =null;try{
files = assetManager.list("MyFolder");}catch(IOException e){Log.e("tag","Failed to get asset file list.", e);}if(files !=null)for(String filename : files){InputStreamin=null;OutputStreamout=null;try{in= assetManager.open("MyFolder/"+filename);File outFile =newFile(getExternalFilesDir(null), filename);if(!(outFile.exists())){// File does not exist...out=newFileOutputStream(outFile);
copyFile(in,out);}}catch(IOException e){Log.e("tag","Failed to copy asset file: "+ filename, e);}finally{if(in!=null){try{in.close();}catch(IOException e){// NOOP}}if(out!=null){try{out.close();}catch(IOException e){// NOOP}}}}}privatevoid copyFile(InputStreamin,OutputStreamout)throwsIOException{byte[] buffer =newbyte[1024];int read;while((read =in.read(buffer))!=-1){out.write(buffer,0, read);}}
Sejauh ini, ini adalah solusi terbaik yang dapat saya temukan di internet. Saya telah menggunakan tautan berikut https://gist.github.com/mhasby/026f02b33fcc4207b302a60645f6e217 , tetapi ia memiliki satu kesalahan yang saya perbaiki dan kemudian berfungsi seperti pesona. Ini kode saya. Anda dapat dengan mudah menggunakannya karena ini adalah kelas java independen.
Seperti yang Anda lihat, cukup buat instance CopyAssetsdi kelas java Anda yang memiliki aktivitas. Sekarang bagian ini penting, sejauh pengujian dan penelitian saya di internet You cannot use AssetManager if the class has no activity,. Ini ada hubungannya dengan konteks kelas java.
Sekarang, c.copyAssets(getApplicationContext())ini adalah cara mudah untuk mengakses metode, di mana cdan contoh CopyAssetskelas. Sesuai kebutuhan saya, saya mengizinkan program untuk menyalin semua file sumber daya saya di dalam assetfolder ke /www/resources/direktori internal saya.
Anda dapat dengan mudah mengetahui bagian di mana Anda perlu membuat perubahan pada direktori sesuai penggunaan Anda. Jangan sungkan untuk menelepon saya jika Anda butuh bantuan.
Berikut ini langkah-langkah untuk menghindari FileUriExposedExceptions, seandainya pengguna telah diberikan WRITE_EXTERNAL_STORAGEizin dan file Anda di assets/pdfs/mypdf.pdf.
private fun openFile(){var inputStream:InputStream?=nullvar outputStream:OutputStream?=nulltry{
val file =File("${activity.getExternalFilesDir(null)}/$PDF_FILE_NAME")if(!file.exists()){
inputStream = activity.assets.open("$PDF_ASSETS_PATH/$PDF_FILE_NAME")
outputStream =FileOutputStream(file)
copyFile(inputStream, outputStream)}
val uri =FileProvider.getUriForFile(
activity,"${BuildConfig.APPLICATION_ID}.provider.GenericFileProvider",
file
)
val intent =Intent(Intent.ACTION_VIEW).apply {
setDataAndType(uri,"application/pdf")
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)}
activity.startActivity(intent)}catch(ex:IOException){
ex.printStackTrace()}catch(ex:ActivityNotFoundException){
ex.printStackTrace()}finally{
inputStream?.close()
outputStream?.flush()
outputStream?.close()}}@Throws(IOException::class)private fun copyFile(input:InputStream, output:OutputStream){
val buffer =ByteArray(1024)var read:Int= input.read(buffer)while(read !=-1){
output.write(buffer,0, read)
read = input.read(buffer)}}
companion object{privateconst val PDF_ASSETS_PATH ="pdfs"privateconst val PDF_FILE_NAME ="mypdf.pdf"}
Jawaban:
Jika ada orang lain yang memiliki masalah yang sama, ini adalah bagaimana saya melakukannya
Referensi: Pindahkan file menggunakan Java
sumber
Failed to copy asset file: myfile.txt java.io.FileNotFoundException: myfile.txt at android.content.res.AssetManager.openAsset(Native Method)
in = assetManager.open("images-wall/"+filename);
mana "gambar-dinding" adalah folder di dalam aset sayaBerdasarkan solusi Anda, saya melakukan sesuatu sendiri untuk memungkinkan subfolder. Seseorang mungkin menganggap ini bermanfaat:
...
...
sumber
assetManager.list(path)
mungkin lambat di perangkat, untuk membuat daftar jalur aset sebelumnya cuplikan ini dapat digunakan dariassets
dir:find . -name "*" -type f -exec ls -l {} \; | awk '{print substr($9,3)}' >> assets.list
finally
blok))Solusi di atas tidak berfungsi karena beberapa kesalahan:
Ini kodenya (saya meninggalkan pernyataan Log tetapi Anda dapat menjatuhkannya sekarang):
EDIT: Mengoreksi tempat yang salah ";" yang melemparkan kesalahan sistematis "tidak dapat membuat dir".
sumber
Saya tahu ini telah dijawab tetapi saya memiliki cara yang sedikit lebih elegan untuk menyalin dari direktori aset ke file di sdcard. Ini tidak memerlukan loop "for" tetapi sebaliknya menggunakan File Streams dan Channels untuk melakukan pekerjaan.
(Catatan) Jika menggunakan semua jenis file terkompresi, APK, PDF, ... Anda mungkin ingin mengubah nama ekstensi file sebelum memasukkan ke dalam aset dan kemudian mengganti nama setelah Anda menyalinnya ke SDcard)
Cara untuk menyalin file tanpa harus mengulanginya.
sumber
This file can not be opened as a file descriptor; it is probably compressed
- ini adalah file pdf. Tahu cara memperbaikinya?coba ini lebih sederhana, ini akan membantu Anda:
sumber
Ini cara ringkas di Kotlin.
sumber
Ini adalah versi yang dibersihkan untuk perangkat Android saat ini, desain metode fungsional sehingga Anda dapat menyalinnya ke kelas AssetsHelper misalnya;)
sumber
Dimodifikasi jawaban SO ini oleh @DannyA
Persiapan
di
src/main/assets
tambahkan folder dengan namafold
Pemakaian
Masuk ke direktori eksternal, temukan semua file dan direktori yang ada dalam aset lipat
sumber
Salin semua file dan direktori dari aset ke folder Anda!
untuk menyalin lebih baik gunakan apache commons io
// INI ADALAH METODE UTAMA UNTUK COPY
sumber
Berdasarkan jawaban Yoram Cohen, berikut adalah versi yang mendukung direktori target tidak statis.
Invoque dengan
copyFileOrDir(getDataDir(), "")
menulis ke folder penyimpanan aplikasi internal / data / data / pkg_name /Hindari menyalin "gambar" dll seperti folder aset palsu
sumber
Menggunakan beberapa konsep dalam jawaban untuk pertanyaan ini, saya menulis sebuah kelas yang disebut
AssetCopier
untuk membuat penyalinan menjadi/assets/
sederhana. Ini tersedia di github dan dapat diakses dengan jitpack.io :Lihat https://github.com/flipagram/android-assetcopier untuk detail lebih lanjut.
sumber
Pada dasarnya ada dua cara untuk melakukan ini.
Pertama, Anda dapat menggunakan AssetManager.open dan, seperti yang dijelaskan oleh Rohith Nandakumar dan beralih ke inputstream.
Kedua, Anda dapat menggunakan AssetManager.openFd , yang memungkinkan Anda menggunakan FileChannel (yang memiliki [transferTo] ( https://developer.android.com/reference/java/nio/channels/FileChannel.html#transferTo(long , long, java.nio.channels.WritableByteChannel)) dan [transferFrom] ( https://developer.android.com/reference/java/nio/channels/FileChannel.html#transferFrom(java.nio.channels.ReadableByteChannel , panjang, long)) metode), jadi Anda tidak perlu mengulangi arus input sendiri.
Saya akan menjelaskan metode openFd di sini.
Kompresi
Pertama, Anda perlu memastikan bahwa file tersebut disimpan tanpa terkompresi. Sistem pengemasan dapat memilih untuk mengompres file apa pun dengan ekstensi yang tidak ditandai sebagai noCompress , dan file yang dikompresi tidak dapat dipetakan dalam memori, jadi Anda harus mengandalkan AssetManager.open dalam kasus itu.
Anda dapat menambahkan ekstensi '.mp3' ke file Anda untuk menghentikannya agar tidak dikompres, tetapi solusi yang tepat adalah dengan memodifikasi file app / build.gradle Anda dan menambahkan baris berikut (untuk menonaktifkan kompresi file PDF)
Pengepakan file
Perhatikan bahwa pembuat paket masih dapat mengemas beberapa file menjadi satu, jadi Anda tidak bisa hanya membaca seluruh file yang diberikan AssetManager kepada Anda. Anda perlu bertanya pada AssetFileDescriptor bagian mana yang Anda butuhkan.
Menemukan bagian yang benar dari file yang dikemas
Setelah Anda memastikan file Anda disimpan tanpa kompresi, Anda dapat menggunakan metode AssetManager.openFd untuk mendapatkan AssetFileDescriptor , yang dapat digunakan untuk mendapatkan FileInputStream (tidak seperti AssetManager.open , yang mengembalikan InputStream ) yang berisi FileChannel . Ini juga berisi offset awal (getStartOffset) dan ukuran (getLength) , yang Anda perlukan untuk mendapatkan bagian file yang benar.
Penerapan
Contoh implementasi diberikan di bawah ini:
Jawaban ini didasarkan pada jawaban JPM .
sumber
ubah bagian kode seperti ini:
contoh sebelum adalah untuk Pdf, untuk contoh .txt
sumber
Gunakan AssetManager , memungkinkan untuk membaca file dalam aset. Kemudian gunakan Java IO biasa untuk menulis file ke sdcard.
Google adalah teman Anda, cari contoh.
sumber
Hai teman-teman, saya melakukan sesuatu seperti ini. Untuk Nth thth Copy Folder dan Files untuk menyalin. Yang Memungkinkan Anda untuk menyalin semua struktur direktori untuk disalin dari Android AssetManager :)
Pada akhirnya, buat Asynctask:
sebut saja Dari aktivitas Anda:
sumber
Sedikit modifikasi jawaban di atas untuk menyalin folder secara rekursif dan untuk mengakomodasi tujuan kustom.
sumber
Berdasarkan solusi Rohith Nandakumar, saya melakukan sesuatu sendiri untuk menyalin file dari subfolder aset (yaitu "aset / MyFolder "). Juga, saya memeriksa apakah file sudah ada di sdcard sebelum mencoba menyalin lagi.
sumber
Sejauh ini, ini adalah solusi terbaik yang dapat saya temukan di internet. Saya telah menggunakan tautan berikut https://gist.github.com/mhasby/026f02b33fcc4207b302a60645f6e217 ,
tetapi ia memiliki satu kesalahan yang saya perbaiki dan kemudian berfungsi seperti pesona. Ini kode saya. Anda dapat dengan mudah menggunakannya karena ini adalah kelas java independen.
Seperti yang Anda lihat, cukup buat instance
CopyAssets
di kelas java Anda yang memiliki aktivitas. Sekarang bagian ini penting, sejauh pengujian dan penelitian saya di internetYou cannot use AssetManager if the class has no activity
,. Ini ada hubungannya dengan konteks kelas java.Sekarang,
c.copyAssets(getApplicationContext())
ini adalah cara mudah untuk mengakses metode, di manac
dan contohCopyAssets
kelas. Sesuai kebutuhan saya, saya mengizinkan program untuk menyalin semua file sumber daya saya di dalamasset
folder ke/www/resources/
direktori internal saya.Anda dapat dengan mudah mengetahui bagian di mana Anda perlu membuat perubahan pada direktori sesuai penggunaan Anda. Jangan sungkan untuk menelepon saya jika Anda butuh bantuan.
sumber
Bagi mereka yang memperbarui ke Kotlin:
Berikut ini langkah-langkah untuk menghindari
FileUriExposedExceptions
, seandainya pengguna telah diberikanWRITE_EXTERNAL_STORAGE
izin dan file Anda diassets/pdfs/mypdf.pdf
.sumber