آموزش خواندن Pdf از پوشه assets در اندروید
سلام دوستان عزیز در این سری از آموزش برنامه نویسی اندروید به آموزش خواندن Pdf از پوشه assets در اندروید می پردازیم برای اینکه یک فایل Pdf را از پوشه assets بخوانیم کافی است بالا کلاس FileOutputStream کار کتیم برای این کار یک کلاس آماده کردیم که با ترکیب کلاس هایی مثل AsyncTask و File به راحتی بتوانیم فایل Pdf را از پوشه assets بخوانیم.
مشکل اصلی در خواندن Pdf از Assets عدم باز شدن فایل بعد از خوانده شدن است برای اینکه pdf به درستی نمایش داده شود لازم است ابتدا از پوشه Assets خوانده شده سپس در Sd Card کپی شده و از آن استفاده شود پس بعد از خواندن باید آن را در Sd Card کپی کنیم.
ابتدا یک کد ساده برای خواند Pdf از Assets را قرار میدهیم سپس با کلاس سفارشی خواندن آن را آموزش میدهیم.
باید در این آموزش از RunTimePermission استفاده کنید تا دسترسی استفاده از حافظه را به دست بیارید.
آموزش این لینک را دانلود کنید.
بعد از قرار دادن RunTimePermission دسترسی زیر را اضافه کنید.
1 | <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> |
و سپس از کد زیر استفاده کنید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | private void CopyReadAssets() { AssetManager assetManager = getAssets(); InputStream in = null; OutputStream out = null; File file = new File(getFilesDir(), "abc.pdf"); try { in = assetManager.open("abc.pdf"); out = openFileOutput(file.getName(), Context.MODE_WORLD_READABLE); copyFile(in, out); in.close(); in = null; out.flush(); out.close(); out = null; } catch (Exception e) { Log.e("tag", e.getMessage()); } Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType( Uri.parse("file://" + getFilesDir() + "/abc.pdf"), "application/pdf"); startActivity(intent); } private void copyFile(InputStream in, OutputStream out) throws IOException { byte[] buffer = new byte[1024]; int read; while ((read = in.read(buffer)) != -1) { out.write(buffer, 0, read); } } } |
کد بالا ابتدا فایل را از پوشه assets خوانده سپس آن را در حافظه اصلی کپی می کند تا قابل استفاده کردن باشد.
برای اینکه کار شما راحت تر باشد یک کلاس سفارشی درست کردیم که کار بالا را انجام میدهد ولی استفاده از آن را پیشنهاد می کنیم چون با استفاده از Asynctask از هرز رفتن زمان و گیر کردن Ui جلوگیری کردیم (در صورتی که فایل Pdf حجیم باشد.)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | public class OpenLocalPDF { private static String TAG = OpenLocalPDF.class.getSimpleName(); private WeakReference<Context> contextWeakReference; private String fileName; public OpenLocalPDF(Context context, String fileName) { this.contextWeakReference = new WeakReference<>(context); this.fileName = fileName.endsWith("pdf") ? fileName : fileName + ".pdf"; } public void execute() { Context context = contextWeakReference.get(); if (context != null) { new CopyFileAsyncTask().execute(); } } private class CopyFileAsyncTask extends AsyncTask<Void, Void, File> { final String appDirectoryName = BuildConfig.APPLICATION_ID; final File fileRoot = new File(Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_DOCUMENTS), appDirectoryName); @Override protected File doInBackground(Void... params) { Context context = contextWeakReference.get(); AssetManager assetManager = context.getAssets(); File file = new File(fileRoot, fileName); InputStream in = null; OutputStream out = null; try { file.mkdirs(); if (file.exists()) { file.delete(); } file.createNewFile(); in = assetManager.open(fileName); Log.d(TAG, "In"); out = new FileOutputStream(file); Log.d(TAG, "Out"); Log.d(TAG, "Copy file"); copyFile(in, out); Log.d(TAG, "Close"); in.close(); out.flush(); out.close(); return file; } catch (Exception e) { Log.e(TAG, e.getMessage()); } return null; } private void copyFile(InputStream in, OutputStream out) throws IOException { byte[] buffer = new byte[1024]; int read; while ((read = in.read(buffer)) != -1) { out.write(buffer, 0, read); } } @Override protected void onPostExecute(File file) { super.onPostExecute(file); Context context = contextWeakReference.get(); Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType( Uri.fromFile(file), "application/pdf"); context.startActivity(intent); } } } |
برای استفاده از این کلاس هم باید مثل زیر عمل کنید.
1 | new OpenLocalPDF(context, 'nameOfPDFStoredInAssets').execute() |
ورودی اول instance مربوط به اکتیویتی و ورودی دوم نام فایل همراه با پسوند یا بدون پسوند مهم نیست.
این آموزش هم به پایان رسید.
موفق و پیروز باشید.