PDFSignaturesSampleActivity.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. /**
  2. * Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
  3. * <p>
  4. * THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
  5. * AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
  6. * UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
  7. * This notice may not be removed from this file.
  8. */
  9. package com.compdfkit.digitalsignature;
  10. import android.Manifest;
  11. import android.os.Build;
  12. import android.os.Bundle;
  13. import android.view.View;
  14. import androidx.activity.result.ActivityResultLauncher;
  15. import com.compdfkit.core.annotation.form.CPDFSignatureWidget;
  16. import com.compdfkit.core.document.CPDFDocument;
  17. import com.compdfkit.digitalsignature.databinding.SignaturesPdfSampleActivityBinding;
  18. import com.compdfkit.tools.common.basic.activity.CBasicPDFActivity;
  19. import com.compdfkit.tools.common.utils.CFileUtils;
  20. import com.compdfkit.tools.common.utils.CPermissionUtil;
  21. import com.compdfkit.tools.common.utils.activitycontracts.CSelectPDFDocumentResultContract;
  22. import com.compdfkit.tools.common.utils.dialog.CAlertDialog;
  23. import com.compdfkit.tools.common.utils.task.CExtractAssetFileTask;
  24. import com.compdfkit.tools.common.utils.threadpools.CThreadPoolUtils;
  25. import com.compdfkit.tools.common.utils.window.CPopupMenuWindow;
  26. import com.compdfkit.tools.common.views.pdfbota.CPDFBOTA;
  27. import com.compdfkit.tools.common.views.pdfbota.CPDFBotaDialogFragment;
  28. import com.compdfkit.tools.common.views.pdfbota.CPDFBotaFragmentTabs;
  29. import com.compdfkit.tools.common.views.pdfview.CPDFViewCtrl;
  30. import com.compdfkit.tools.common.views.pdfview.CPreviewMode;
  31. import com.compdfkit.tools.signature.CertificateDigitalDatas;
  32. import com.compdfkit.tools.signature.bean.CPDFDocumentSignInfo;
  33. import com.compdfkit.tools.signature.info.signlist.CPDFCertDigitalSignListDialog;
  34. import com.compdfkit.tools.signature.pdfproperties.pdfsign.CDigitalSignatureWidgetImpl;
  35. import com.compdfkit.tools.viewer.pdfsearch.CSearchResultDialogFragment;
  36. import com.compdfkit.ui.reader.CPDFReaderView;
  37. import java.util.ArrayList;
  38. public class PDFSignaturesSampleActivity extends CBasicPDFActivity {
  39. /**
  40. * assets folder pdf file
  41. */
  42. public static final String QUICK_START_GUIDE = "4KDAN_adobe + chunghwa.pdf";
  43. private SignaturesPdfSampleActivityBinding binding;
  44. private CViewerScreenStatusManager screenStatusManager;
  45. private ActivityResultLauncher<Void> selectDocumentLauncher = registerForActivityResult(new CSelectPDFDocumentResultContract(), uri -> {
  46. if (uri != null) {
  47. CFileUtils.takeUriPermission(this, uri);
  48. binding.pdfView.setViewMode(CPDFReaderView.ViewMode.VIEW);
  49. screenStatusManager.constraintHide(binding.signStatusView);
  50. binding.signatureToolBar.reset();
  51. binding.pdfView.openPDF(uri);
  52. }
  53. });
  54. @Override
  55. protected void onCreate(Bundle savedInstanceState) {
  56. super.onCreate(savedInstanceState);
  57. binding = SignaturesPdfSampleActivityBinding.inflate(getLayoutInflater());
  58. setContentView(binding.getRoot());
  59. binding.pdfView.setViewMode(CPDFReaderView.ViewMode.VIEW);
  60. screenStatusManager = new CViewerScreenStatusManager(binding);
  61. binding.pdfView.getCPdfReaderView().setFormFieldHighlight(true);
  62. initToolbarListener();
  63. initSearchBar();
  64. initSignatureToolbar();
  65. //Extract PDF files from the Android assets folder
  66. CExtractAssetFileTask.extract(this, QUICK_START_GUIDE, QUICK_START_GUIDE, (filePath) -> {
  67. binding.pdfView.openPDF(filePath);
  68. });
  69. resetContextMenu(binding.pdfView, CPreviewMode.Signature);
  70. binding.pdfView.setOnTapMainDocAreaCallback(() -> {
  71. screenStatusManager.fillScreenChange();
  72. });
  73. binding.pdfView.getCPdfReaderView().setMinScaleEnable(false);
  74. registerSignaturesHelper(binding.pdfView);
  75. initFormAttr(binding.pdfView);
  76. }
  77. private void initToolbarListener() {
  78. binding.pdfToolBar.addMode(CPreviewMode.Viewer);
  79. binding.pdfToolBar.addMode(CPreviewMode.Signature);
  80. binding.pdfToolBar.selectMode(CPreviewMode.Signature);
  81. binding.pdfToolBar.setPreviewModeChangeListener(mode -> {
  82. binding.pdfToolBar.selectMode(mode);
  83. screenStatusManager.changeWindowStatus(mode);
  84. binding.pdfView.setViewMode(CPDFReaderView.ViewMode.VIEW);
  85. binding.signatureToolBar.reset();
  86. resetContextMenu(binding.pdfView, mode);
  87. });
  88. binding.pdfToolBar.setSearchBtnClickListener(v -> {
  89. binding.pdfToolBar.setVisibility(View.GONE);
  90. binding.pdfSearchToolBar.setVisibility(View.VISIBLE);
  91. binding.pdfSearchToolBar.showKeyboard();
  92. binding.pdfView.setViewMode(CPDFReaderView.ViewMode.VIEW);
  93. binding.signatureToolBar.reset();
  94. });
  95. binding.pdfToolBar.setBoTaBtnClickListener(v -> {
  96. //Show a fragment of the PDF thumbnail and a dialog fragment of the PDF outline list.
  97. CPDFBotaDialogFragment boTaDialogFragment = CPDFBotaDialogFragment.newInstance();
  98. boTaDialogFragment.initWithPDFView(binding.pdfView);
  99. CPDFBotaFragmentTabs outlineTabs = new CPDFBotaFragmentTabs(CPDFBOTA.OUTLINE, getString(R.string.tools_outlines));
  100. CPDFBotaFragmentTabs bookmarks = new CPDFBotaFragmentTabs(CPDFBOTA.BOOKMARKS, getString(R.string.tools_bookmarks));
  101. ArrayList<CPDFBotaFragmentTabs> tabs = new ArrayList<>();
  102. tabs.add(outlineTabs);
  103. tabs.add(bookmarks);
  104. boTaDialogFragment.setBotaDialogTabs(tabs);
  105. boTaDialogFragment.show(getSupportFragmentManager(), "boTaDialogFragment");
  106. });
  107. binding.pdfToolBar.setThumbnailBtnClickListener(v -> {
  108. CPDFBotaDialogFragment boTaDialogFragment = CPDFBotaDialogFragment.newInstance();
  109. boTaDialogFragment.initWithPDFView(binding.pdfView);
  110. CPDFBotaFragmentTabs thumbnailTabs = new CPDFBotaFragmentTabs(CPDFBOTA.THUMBNAIL, getString(R.string.tools_thumbnails));
  111. ArrayList<CPDFBotaFragmentTabs> tabs = new ArrayList<>();
  112. tabs.add(thumbnailTabs);
  113. boTaDialogFragment.setBotaDialogTabs(tabs);
  114. boTaDialogFragment.show(getSupportFragmentManager(), "boTaDialogFragment");
  115. });
  116. binding.pdfToolBar.setMoreBtnClickListener(v -> {
  117. v.setSelected(true);
  118. //Show the PDF settings dialog fragment
  119. CPopupMenuWindow menuWindow = new CPopupMenuWindow(this);
  120. menuWindow.addItem(R.drawable.tools_ic_preview_settings, R.string.tools_view_setting, v1 -> {
  121. showDisplaySettings(binding.pdfView);
  122. });
  123. menuWindow.addItem(R.drawable.tools_ic_document_info, R.string.tools_document_info, v1 -> {
  124. showDocumentInfo(binding.pdfView);
  125. });
  126. menuWindow.addItem(R.drawable.tools_ic_share, R.string.tools_share, v1 -> {
  127. sharePDF(binding.pdfView);
  128. });
  129. menuWindow.addItem(R.drawable.tools_ic_new_file, R.string.tools_open_document, v1 -> {
  130. if (CPermissionUtil.hasStoragePermissions(this)) {
  131. selectDocument();
  132. } else {
  133. requestStoragePermissions();
  134. }
  135. binding.pdfView.savePDF((filePath, pdfUri) -> {
  136. }, e -> {
  137. });
  138. });
  139. menuWindow.setOnDismissListener(() -> v.setSelected(false));
  140. menuWindow.showAsDropDown(v);
  141. });
  142. }
  143. private void requestStoragePermissions() {
  144. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
  145. CPermissionUtil.openManageAllFileAppSettings(this);
  146. } else {
  147. multiplePermissionResultLauncher.launch(STORAGE_PERMISSIONS, result -> {
  148. if (CPermissionUtil.hasStoragePermissions(this)) {
  149. selectDocument();
  150. } else {
  151. if (!CPermissionUtil.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
  152. showPermissionsRequiredDialog();
  153. }
  154. }
  155. });
  156. }
  157. }
  158. private void initSearchBar() {
  159. binding.pdfSearchToolBar.initWithPDFView(binding.pdfView);
  160. binding.pdfSearchToolBar.onSearchQueryResults(list -> {
  161. CSearchResultDialogFragment searchResultDialog = new CSearchResultDialogFragment();
  162. searchResultDialog.show(getSupportFragmentManager(), "searchResultDialogFragment");
  163. searchResultDialog.setSearchTextInfos(list);
  164. searchResultDialog.setOnClickSearchItemListener(clickItem -> {
  165. binding.pdfView.getCPdfReaderView().setDisplayPageIndex(clickItem.page);
  166. binding.pdfView.getCPdfReaderView().getTextSearcher().searchBegin(clickItem.page, clickItem.textRangeIndex);
  167. searchResultDialog.dismiss();
  168. });
  169. });
  170. binding.pdfSearchToolBar.setExitSearchListener(() -> {
  171. binding.pdfToolBar.setVisibility(View.VISIBLE);
  172. binding.pdfSearchToolBar.setVisibility(View.GONE);
  173. binding.pdfSearchToolBar.hideKeyboard();
  174. });
  175. }
  176. private void initSignatureToolbar() {
  177. binding.signStatusView.initWithPDFView(binding.pdfView);
  178. binding.signStatusView.getBtnDetails().setOnClickListener(v -> {
  179. CPDFCertDigitalSignListDialog signListDialog = CPDFCertDigitalSignListDialog.newInstance();
  180. signListDialog.initWithPDFView(binding.pdfView);
  181. signListDialog.setDialogDismissListener(this::verifyDocumentSignStatus);
  182. signListDialog.show(getSupportFragmentManager(), "signListDialog");
  183. });
  184. binding.signatureToolBar.initWithPDFView(binding.pdfView);
  185. binding.signatureToolBar.getVerifySignButton().setOnClickListener(v -> {
  186. verifyDocumentSignStatus();
  187. });
  188. }
  189. /**
  190. *
  191. */
  192. private void verifyDocumentSignStatus() {
  193. CPDFDocument document = binding.pdfView.getCPdfReaderView().getPDFDocument();
  194. if (CertificateDigitalDatas.hasDigitalSignature(document)) {
  195. CThreadPoolUtils.getInstance().executeIO(() -> {
  196. CPDFDocumentSignInfo status = CertificateDigitalDatas.verifyDocumentSignStatus(document);
  197. runOnUiThread(() -> {
  198. if (status != null) {
  199. binding.signStatusView.setStatus(status);
  200. screenStatusManager.manager.bindTopToolView(binding.signStatusView);
  201. screenStatusManager.constraintShow(binding.signStatusView);
  202. }
  203. });
  204. });
  205. } else {
  206. if (binding.signStatusView.getVisibility() == View.VISIBLE) {
  207. screenStatusManager.manager.removeAndHideToolView(binding.signStatusView);
  208. screenStatusManager.constraintHide(binding.signStatusView);
  209. }
  210. }
  211. }
  212. private void registerSignaturesHelper(CPDFViewCtrl pdfView) {
  213. pdfView.getCPdfReaderView().getAnnotImplRegistry()
  214. .registImpl(CPDFSignatureWidget.class, CDigitalSignatureWidgetImpl.class);
  215. }
  216. private void selectDocument() {
  217. if (binding.pdfView.getCPdfReaderView().getPDFDocument() == null) {
  218. selectDocumentLauncher.launch(null);
  219. return;
  220. }
  221. if (!binding.pdfView.getCPdfReaderView().getPDFDocument().hasChanges()) {
  222. selectDocumentLauncher.launch(null);
  223. return;
  224. }
  225. CAlertDialog alertDialog = CAlertDialog.newInstance(getString(com.compdfkit.tools.R.string.tools_save_title), getString(com.compdfkit.tools.R.string.tools_save_message));
  226. alertDialog.setConfirmClickListener(v -> {
  227. //save pdf document
  228. binding.pdfView.savePDF((filePath, pdfUri) -> {
  229. alertDialog.dismiss();
  230. selectDocumentLauncher.launch(null);
  231. }, e -> {
  232. alertDialog.dismiss();
  233. selectDocumentLauncher.launch(null);
  234. });
  235. });
  236. alertDialog.setCancelClickListener(v -> {
  237. alertDialog.dismiss();
  238. selectDocumentLauncher.launch(null);
  239. });
  240. alertDialog.show(getSupportFragmentManager(), "alertDialog");
  241. }
  242. }