1、把PDF文件复制到raw目录下
(1)新建一个Android Resource Directory
(2)Resource type 改成 raw
(3) 把PDF文件复制到raw目录下
2、activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"xmlns:app="http://schemas.android.com/apk/res-auto"android:id="@+id/main"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><Buttonandroid:id="@+id/button1"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="打开PDF"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintTop_toTopOf="parent" /></LinearLayout>
3、MainActivity.java
java">package com.example.openpdf;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;public class MainActivity extends AppCompatActivity {String fileName;InputStream inputStream;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button buttonOpenPdf = findViewById(R.id.button1);buttonOpenPdf.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {fileName = "one_one.pdf";inputStream = getResources().openRawResource(R.raw.one_one);request();}});}//检查请求private void request(){//权限检查if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {//如果返回值为true,意味着应用尚未获得该权限ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);}else {checkAndSavePdf();}if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE}, 2);}else {openPdfFile();}}//权限请求结果处理public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);if (requestCode == 1) {//如果用户同意授权访问if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {checkAndSavePdf();}else {Toast.makeText(this, "存储权限被拒绝", Toast.LENGTH_SHORT).show();}}if (requestCode == 2) {if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {openPdfFile();} else {Toast.makeText(this, "读取外部存储权限被拒绝", Toast.LENGTH_SHORT).show();}}}//检查文件是否已经保存private void checkAndSavePdf() {//check检查File pdfFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS + "/math"),fileName);if (!pdfFile.exists()) {savePdf();}}//保存PDFprivate void savePdf() {ContentResolver contentResolver = getContentResolver();ContentValues contentValues = new ContentValues();// 设置文件名contentValues.put(MediaStore.Downloads.DISPLAY_NAME, fileName);// 设置文件 MIME 类型contentValues.put(MediaStore.Downloads.MIME_TYPE, "application/pdf");if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {// 设置文件相对路径为 Downloads 目录contentValues.put(MediaStore.Downloads.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS+"/math");}// 插入文件信息到 MediaStore 并获取 UriUri uri = contentResolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, contentValues);if (uri != null) {try {// 打开输出流OutputStream outputStream = contentResolver.openOutputStream(uri);if (outputStream != null) {byte[] buffer = new byte[1024];int length;// 从输入流读取数据并写入输出流while ((length = inputStream.read(buffer)) > 0) {outputStream.write(buffer, 0, length);}// 关闭输出流outputStream.close();// 关闭输入流inputStream.close();}} catch (IOException e) {e.printStackTrace();}}}//打开PDFprivate void openPdfFile() {// 假设 PDF 文件在外部存储的 Downloads 目录下File pdfFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS+"/math"),fileName);if (pdfFile.exists()) {Uri uri;// 获取文件的 Uriif (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {// 使用 FileProvider 生成 content:// 类型的 Uriuri = FileProvider.getUriForFile(this, getPackageName() + ".fileprovider", pdfFile);}else {uri = Uri.fromFile(pdfFile);}// 创建隐式意图Intent intent = new Intent(Intent.ACTION_VIEW);intent.setDataAndType(uri, "application/pdf");intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);}// 检查是否有应用可以处理该意图if (getPackageManager().queryIntentActivities(intent, 0).size() > 0) {startActivity(intent);}else {Toast.makeText(this, "没有可用的 PDF 阅读器", Toast.LENGTH_SHORT).show();}} else {Toast.makeText(this, "PDF 文件不存在", Toast.LENGTH_SHORT).show();}}}
4、AndroidManifest.xml
在 AndroidManifest.xml
中添加以下代码:
<!-- 声明写入外部存储的权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- 声明读取外部存储的权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /><providerandroid:name="androidx.core.content.FileProvider"android:authorities="${applicationId}.fileprovider"android:exported="false"android:grantUriPermissions="true"><meta-dataandroid:name="android.support.FILE_PROVIDER_PATHS"android:resource="@xml/file_paths" />
</provider>
AndroidManifest.xml 完整代码:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools" ><!-- 声明写入外部存储的权限 --><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><!-- 声明读取外部存储的权限 --><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /><applicationandroid:allowBackup="true"android:dataExtractionRules="@xml/data_extraction_rules"android:fullBackupContent="@xml/backup_rules"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.OpenPDF"tools:targetApi="31" ><activityandroid:name=".MainActivity"android:exported="true" ><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><providerandroid:name="androidx.core.content.FileProvider"android:authorities="${applicationId}.fileprovider"android:exported="false"android:grantUriPermissions="true"><meta-dataandroid:name="android.support.FILE_PROVIDER_PATHS"android:resource="@xml/file_paths" /></provider></application></manifest>
5、创建 file_paths.xml
文件
在 res/xml
目录下创建 file_paths.xml
文件,内容如下:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android"><external-path name="external_files" path="." />
</paths>
3、