09357900665 Basic4x@gmail.com تایم کاری : شنبه تا پنج شنبه تهران ، ولیعصر

خواندن Pdf از پوشه assets در اندروید استودیو

سلام دوستان عزیز در این سری از آموزش برنامه نویسی اندروید به آموزش خواندن Pdf از پوشه assets در اندروید می پردازیم برای اینکه یک فایل Pdf را از پوشه assets بخوانیم کافی است بالا کلاس FileOutputStream کار کتیم برای این کار یک کلاس آماده کردیم که با ترکیب کلاس هایی مثل AsyncTask و File به راحتی بتوانیم فایل Pdf را از پوشه assets بخوانیم.

 

مشکل اصلی در خواندن Pdf از Assets عدم باز شدن فایل بعد از خوانده شدن است برای اینکه pdf به درستی نمایش داده شود لازم است ابتدا از پوشه Assets خوانده شده سپس در Sd Card کپی شده و از آن استفاده شود پس بعد از خواندن باید آن را در Sd Card کپی کنیم.

ابتدا یک کد ساده برای خواند Pdf از Assets را قرار میدهیم سپس با کلاس سفارشی خواندن آن را آموزش میدهیم.

باید در این آموزش از RunTimePermission استفاده کنید تا دسترسی استفاده از حافظه را به دست بیارید.

بعد از قرار دادن RunTimePermission دسترسی زیر را اضافه کنید.

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

و سپس کد زیر :

       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 حجیم باشد.)

 

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

        }
    }
}

برای استفاده از این کلاس هم باید مثل زیر عمل کنید.

new OpenLocalPDF(context, 'nameOfPDFStoredInAssets').execute()

ورودی اول instance مربوط به اکتیویتی و ورودی دوم نام فایل همراه با پسوند یا بدون پسوند مهم نیست.

مجتبی حسین زاده

65 مطلب منتشر شده

مجتبی حسین زاده سلام خدمت شما، مجتبی هستم مدیر و موسس اندروید راست چین، بیش از 15 سال تو حوزه برنامه نویسی اندروید و وب هستم و در کنار وبلاگ نویسی و طراحی سایت و همچنین برنامه نویسی اندروید در زمینه شبکه و دوربین های مداربسته نیز فعالیت دارم. خوشحال میشم اگه سوالی داشته باشید با بنده مطرح کنید.

درباره این مطلب نظر دهید !