Как открыть файл PDF из папки активов

Попытка открыть файл PDF из папки активов при нажатии на кнопку

public class CodSecreen extends AppCompatActivity {
    PDFView pdfView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_cod_secreen);
        pdfView=(PDFView)findViewById(R.id.pdf);
        Intent intent = getIntent();
        String str = intent.getStringExtra("message");
        if (str.equals(getResources().getString(R.string.introduction))){
            pdfView.fromAsset("phpvariable.pdf").load();
        }
    }
}

передавая строковое значение кнопки

bttn1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            String str = bttn1.getText().toString();
            Intent i=new Intent(DetailSecreen.this,CodSecreen.class);
            startActivity(i);
        }
    });

1 ответ

Обновление Android Q

Это старый вопрос, но в Android Q есть некоторые изменения из-за нового разрешения / системы доступа к файлам. Теперь невозможно просто сохранить файл PDF в общей папке. Я решил эту проблему, создав копию PDF-файла вcacheпапка в data/data моего приложения. При таком подходе разрешениеWRITE_EXTERNAL_STORAGE больше не требуется.

Откройте файл PDF:

fun openPdf(){
    // Open the PDF file from raw folder
    val inputStream = resources.openRawResource(R.raw.mypdf)

    // Copy the file to the cache folder
    inputStream.use { inputStream ->
        val file = File(cacheDir, "mypdf.pdf")
        FileOutputStream(file).use { output ->
            val buffer = ByteArray(4 * 1024) // or other buffer size
            var read: Int
            while (inputStream.read(buffer).also { read = it } != -1) {
                output.write(buffer, 0, read)
            }
            output.flush()
        }
    }

    val cacheFile = File(cacheDir, "mypdf.pdf")

    // Get the URI of the cache file from the FileProvider
    val uri = FileProvider.getUriForFile(this, "$packageName.provider", cacheFile)
    if (uri != null) {
        // Create an intent to open the PDF in a third party app
        val pdfViewIntent = Intent(Intent.ACTION_VIEW)
        pdfViewIntent.data = uri
        pdfViewIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
        startActivity(Intent.createChooser(pdfViewIntent, "Choos PDF viewer"))
    }
}

Конфигурация провайдера внутри provider_paths.xmlдля доступа к файлу вне вашего собственного приложения. Это позволяет получить доступ ко всем файлам вcache папка:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <cache-path
        name="cache-files"
        path="/" />
</paths>

Добавьте конфигурацию поставщика файлов в свой AndroidManifest.xml

<provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="${applicationId}.provider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/provider_paths" />
</provider>

Это можно улучшить, скопировав файлы только один раз и проверив, существует ли уже файл, и заменив его. Поскольку открытие PDF-файлов не является большой частью моего приложения, я просто сохраняю его в папке кеша и переопределяю каждый раз, когда пользователь открывает PDF-файл.

Вы можете сделать это в четыре шага ☺

Шаг 1: Создайте папку ресурсов в вашем проекте и поместите в нее PDF

:: Например: assets/MyPdf.pdf

Шаг 2. Поместите следующий код в свой класс [onCreate]:

Button read = (Button) findViewById(R.id.read);


// Press the button and Call Method => [ ReadPDF ]
read.setOnClickListener(new OnClickListener() {
       public void onClick(View view) {
            ReadPDF();
    }
    });
    }
    private void ReadPDF()
    {
        AssetManager assetManager = getAssets();
        InputStream in = null;
        OutputStream out = null;
        File file = new File(getFilesDir(), "MyPdf.pdf"); //<= PDF file Name
        try
        {
            in = assetManager.open("MyPdf.pdf"); //<= PDF file Name
            out = openFileOutput(file.getName(), Context.MODE_WORLD_READABLE);
            copypdf(in, out);
            in.close();
            in = null;
            out.flush();
            out.close();
            out = null;
        } catch (Exception e)
        {
            System.out.println(e.getMessage());
        }
        PackageManager packageManager = getPackageManager();
        Intent testIntent = new Intent(Intent.ACTION_VIEW);
        testIntent.setType("application/pdf");
        List list = packageManager.queryIntentActivities(testIntent, PackageManager.MATCH_DEFAULT_ONLY);
        if (list.size() > 0 && file.isFile()) {
            //Toast.makeText(MainActivity.this,"Pdf Reader Exist !",Toast.LENGTH_SHORT).show();
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_VIEW);
            intent.setDataAndType(
                Uri.parse("file://" + getFilesDir() + "/MyPdf.pdf"),
                "application/pdf");
            startActivity(intent);
            }
            else {
            // show toast when => The PDF Reader is not installed !
            Toast.makeText(MainActivity.this,"Pdf Reader NOT Exist !",Toast.LENGTH_SHORT).show();
            }
        }
        private void copypdf(InputStream in, OutputStream out) throws IOException {
        byte[] buffer = new byte[1024];
        int read;
        while ((read = in.read(buffer)) != -1)
        {
            out.write(buffer, 0, read);
        }
    }
}

Шаг 3: Поместите следующий код в свой макет:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center">

    <Button
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:text="Read PDF !"
        android:id="@+id/read"/>

</LinearLayout>

Шаг 4: Разрешение:

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

Это все:)

Удачи!

Другие вопросы по тегам