在 android studio 中设置 pdf 文件密码

Set pdf file password in android studio

我正在使用这种方法通过 pdfDocument 库生成 pdf 文件。这是我的代码包装在 MainActivity.java 文件

声明的变量

private static final int PERMISSION_REQUEST_CODE = 200;
Button generatePDFbtn;

// declaring width and height
// for our PDF file.
int pageHeight = 1120;
int pagewidth = 792;

// creating a bitmap variable
// for storing our images
Bitmap bmp, scaledbmp;

覆盖 oncreate 函数

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inScaled = false;

    generatePDFbtn = findViewById(R.id.idBtnGeneratePDF);
    bmp = BitmapFactory.decodeResource(this.getResources(), R.drawable.test.png, options);
    scaledbmp = Bitmap.createScaledBitmap(bmp, 140, 140, false);

    // below code is used for
    // checking our permissions.
    if (checkPermission()) {
        Toast.makeText(this, "Permission Granted", Toast.LENGTH_SHORT).show();
    } else {
        requestPermission();
    }

    generatePDFbtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // calling method to
            // generate our PDF file.
            try {
                generatePDF();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
    });
}

生成PDF函数

private void generatePDF() throws FileNotFoundException {
      PdfDocument pdfDocument = new PdfDocument();
      Paint paint = new Paint();
      Paint title = new Paint();
      PdfDocument.PageInfo mypageInfo = new PdfDocument.PageInfo.Builder(pagewidth, pageHeight, 1).create();

      PdfDocument.Page myPage = pdfDocument.startPage(mypageInfo);

      Canvas canvas = myPage.getCanvas();

      canvas.drawBitmap(scaledbmp, 56, 40, paint);

      title.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.NORMAL));
      title.setTextSize(15);
      title.setColor(ContextCompat.getColor(this, R.color.purple_200));

      canvas.drawText("A portal for IT professionals.", 209, 100, title);
      canvas.drawText("Geeks for Geeks", 209, 80, title);

      title.setTypeface(Typeface.defaultFromStyle(Typeface.NORMAL));
      title.setColor(ContextCompat.getColor(this, R.color.purple_200));
      title.setTextSize(15);

      title.setTextAlign(Paint.Align.CENTER);
      canvas.drawText("This is sample document which we have created.", 396, 560, title);

      pdfDocument.finishPage(myPage);

      File directoryFile = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);

      File saveFile = new File(directoryFile, "test.pdf");

      try {
          pdfDocument.writeTo(new FileOutputStream(saveFile));
          Toast.makeText(MainActivity.this, "PDF file generated successfully.", Toast.LENGTH_SHORT).show();
      } catch (IOException e) {
          e.printStackTrace();
      }
      pdfDocument.close();
  }

我到处搜索如何为 pdf 文件设置密码,似乎 pdfDocument 库没有提供这样做的功能。在 android 中创建 pdf 文件时是否有任何库或设置密码的方法?

注意: 我尝试使用以下版本的 itext core 7 7.2.0,但由以下代码生成的 pdf 文件已损坏。我试图将 pdf 库降级为 5.5.3.1 的工作版本,但该版本不再存在。无论如何,这是我使用 itext core 7

实现生成 pdf 的方式
String pdfPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString();
        File file = new File(pdfPath, "test.pdf");

        PdfWriter writer = new PdfWriter(file);
        PdfDocument pdfDocument = new PdfDocument(writer);
        Document document = new Document(pdfDocument);

        Paragraph paragraph = new Paragraph("Technology").setTextAlignment(TextAlignment.CENTER)
                .setFontSize(15);
        document.add(paragraph);
        document.close(); 

我的问题使用 itext core 7.1^ 解决了,正如上面提到的 K J。对于那些想知道实现或代码的人,这里是如何:

build.gradle

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    ... 
    implementation 'com.itextpdf:itext7-core:7.1.13' // add this library
}

AndroidManifest

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

权限检查器

public class PermissionsChecker {

    /**
     * Permission List
     */
    public static String[] REQUIRED_PERMISSION = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE};

    /**
     * Context
     */
    private final Context context;

    public PermissionsChecker(Context context) {
        this.context = context;
    }

    public boolean lacksPermissions(String... permissions) {
        for (String permission : permissions) {
            if (lacksPermission(permission)) {
                return true;
            }
        }
        return false;
    }

    private boolean lacksPermission(String permission) {
        return ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_DENIED;
    }
}

权限Activity

public class PermissionsActivity extends AppCompatActivity {

    public static final int PERMISSIONS_GRANTED = 0;
    public static final int PERMISSIONS_DENIED = 1;

    public static final int PERMISSION_REQUEST_CODE = 0;

    private static final String EXTRA_PERMISSIONS = "com.koops.sales.EXTRA_PERMISSIONS";
    private static final String PACKAGE_URL_SCHEME = "package:";

    private PermissionsChecker checker;
    private boolean requiresCheck;

    public static void startActivityForResult(@NonNull Activity activity, int requestCode, String... permissions) {
        Intent intent = new Intent(activity, PermissionsActivity.class);
        intent.putExtra(EXTRA_PERMISSIONS, permissions);
        ActivityCompat.startActivityForResult(activity, intent, requestCode, null);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getIntent() == null || !getIntent().hasExtra(EXTRA_PERMISSIONS)) {
            throw new RuntimeException("This Activity needs to be launched using the static startActivityForResult() method.");
        }
        //setContentView(R.layout.activity_permissions);

        checker = new PermissionsChecker(this);
        requiresCheck = true;
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (requiresCheck) {
            String[] permissions = getPermissions();

            if (checker.lacksPermissions(permissions)) {
                requestPermissions(permissions);
            } else {
                allPermissionsGranted();
            }
        } else {
            requiresCheck = true;
        }
    }

    private String[] getPermissions() {
        return getIntent().getStringArrayExtra(EXTRA_PERMISSIONS);
    }

    private void requestPermissions(@NonNull String... permissions) {
        ActivityCompat.requestPermissions(this, permissions, PERMISSION_REQUEST_CODE);
    }

    private void allPermissionsGranted() {
        setResult(PERMISSIONS_GRANTED);
        finish();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == PERMISSION_REQUEST_CODE && hasAllPermissionsGranted(grantResults)) {
            requiresCheck = true;
            allPermissionsGranted();
        } else {
            requiresCheck = false;
            showMissingPermissionDialog();
        }
    }

    private boolean hasAllPermissionsGranted(@NonNull int[] grantResults) {
        for (int grantResult : grantResults) {
            if (grantResult == PackageManager.PERMISSION_DENIED) {
                return false;
            }
        }
        return true;
    }

    private void showMissingPermissionDialog() {
        AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(PermissionsActivity.this);
        dialogBuilder.setTitle(R.string.string_permission_help);
        dialogBuilder.setMessage(R.string.string_permission_help_text);
        dialogBuilder.setNegativeButton(R.string.string_permission_quit, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                setResult(PERMISSIONS_DENIED);
                finish();
            }
        });
        dialogBuilder.setPositiveButton(R.string.string_settings, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                startAppSettings();
            }
        });
        dialogBuilder.show();
    }

    private void startAppSettings() {
        Intent intent = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        intent.setData(Uri.parse(PACKAGE_URL_SCHEME + getPackageName()));
        startActivity(intent);
    }
}

主要Activity

import com.myapplication.R;
import com.myapplication.PermissionsActivity;
import com.myapplication.PermissionsChecker;
....

import static com.myapplication.permission.PermissionsActivity.PERMISSION_REQUEST_CODE;
import static com.myapplication.PermissionsChecker.REQUIRED_PERMISSION;

public class MainActivity extends AppCompatActivity {
   PermissionChecker checker;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
      ...

      String dest = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString() + "/test.pdf";
      checker = new PermissionsChecker(this);
      if (checker.lacksPermissions(REQUIRED_PERMISSION)) {
         PermissionsActivity.startActivityForResult(MainActivity.this, PERMISSION_REQUEST_CODE, REQUIRED_PERMISSION);
    } else {
        generatePDF(dest);
    }
  }

  private void generatePDF(String dest) {
      WriterProperties writerProperties = new WriterProperties();
      writerProperties.setStandardEncryption("1234".getBytes(), "1234".getBytes(), EncryptionConstants.ALLOW_PRINTING, EncryptionConstants.ENCRYPTION_AES_128);
      PdfWriter pdfWriter = new PdfWriter(new FileOutputStream(dest), writerProperties);
      PdfDocument pdfDocument = new PdfDocument(pdfWriter);
      Document document = new Document(pdfDocument, PageSize.A4, true);

   // Init pdf property for writing
      Color mColorAccent = new DeviceRgb(153, 204, 255);
      Color mColorBlack = new DeviceRgb(0, 0, 0);
      float mHeadingFontSize = 20.0f;
      float mValueFontSize = 26.0f;

      PdfFont font = PdfFontFactory.createFont("assets/fonts/brandon_medium.otf", "UTF-8", true);

      Text mOrderIdValueChunk = new Text("#Example pdf password").setFont(font).setFontSize(mValueFontSize).setFontColor(mColorBlack);
      Paragraph mOrderIdValueParagraph = new Paragraph(mOrderIdValueChunk);
      document.add(mOrderIdValueParagraph);
       
      document.close();
      Toast.makeText(mContext, "Pdf successfully created with password :)", Toast.LENGTH_SHORT).show();

       } catch (IOException e) {
           Log.e("TAG", e.getLocalizedMessage());
       } catch (ActivityNotFoundException eActivity) {
           Toast.makeText(mContext, "No application found to open this file.", Toast.LENGTH_SHORT).show();
       }
   }

   @Override
   protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == PermissionsActivity.PERMISSIONS_GRANTED) {
        Toast.makeText(mContext, "Permission Granted to Save", Toast.LENGTH_SHORT).show();
    } else {
        Toast.makeText(mContext, "Permission not granted, Try again!", Toast.LENGTH_SHORT).show();
    }

  // to open pdf file
  private void openPDF(String dest) {
      new Handler().postDelayed(new Runnable() {
          @Override
          public void run() {
              try {
                Intent intent = new Intent(Intent.ACTION_VIEW);
                Uri uri = Uri.fromFile(new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) +
                        "/" + dest));
                intent.setDataAndType(uri, "application/pdf");
                StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
                StrictMode.setVmPolicy(builder.build());
                intent = Intent.createChooser(intent, "Open File");
                intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
                startActivity(intent);
              } catch (Exception e) {
                  Log.d("TAG", "run: Error");
              }
          }
      }, 1000);
  }
}

结论

设置pdf文件密码的主要部分是使用WriterProperties作为PdfWriter对象的第二个参数。

WriterProperties writerProperties = new WriterProperties();
writerProperties.setStandardEncryption("1234".getBytes(), "1234".getBytes(), EncryptionConstants.ALLOW_PRINTING, EncryptionConstants.ENCRYPTION_AES_128);

PdfWriter pdfWriter = new PdfWriter(new FileOutputStream(dest), writerProperties);