PDFAnnotationSampleActivity.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. package com.compdfkit.annotations;
  2. import android.Manifest;
  3. import android.content.Intent;
  4. import android.net.Uri;
  5. import android.os.Build;
  6. import android.os.Bundle;
  7. import android.provider.Settings;
  8. import android.view.View;
  9. import androidx.activity.result.ActivityResultLauncher;
  10. import androidx.activity.result.contract.ActivityResultContracts;
  11. import androidx.annotation.NonNull;
  12. import com.compdfkit.annotations.CAnnotSampleScreenManager;
  13. import com.compdfkit.annotations.R;
  14. import com.compdfkit.annotations.databinding.AnnotationPdfSampleActivityBinding;
  15. import com.compdfkit.core.annotation.CPDFAnnotation;
  16. import com.compdfkit.tools.common.activity.CBasicActivity;
  17. import com.compdfkit.tools.common.utils.CFileUtils;
  18. import com.compdfkit.tools.common.utils.dialog.CAlertDialog;
  19. import com.compdfkit.tools.common.utils.task.CExtractAssetFileTask;
  20. import com.compdfkit.tools.common.utils.window.CPopupMenuWindow;
  21. import com.compdfkit.tools.common.views.pdfbota.CPDFBOTA;
  22. import com.compdfkit.tools.common.views.pdfbota.CPDFBotaDialogFragment;
  23. import com.compdfkit.tools.common.views.pdfbota.CPDFBotaFragmentTabs;
  24. import com.compdfkit.tools.common.views.pdfproperties.CAnnotationType;
  25. import com.compdfkit.tools.common.views.pdfview.CPreviewMode;
  26. import com.compdfkit.tools.viewer.pdfsearch.CSearchResultDialogFragment;
  27. import java.util.ArrayList;
  28. import java.util.Arrays;
  29. import pub.devrel.easypermissions.AppSettingsDialog;
  30. import pub.devrel.easypermissions.EasyPermissions;
  31. public class PDFAnnotationSampleActivity extends CBasicActivity {
  32. /**
  33. * assets folder pdf file
  34. */
  35. public static final String QUICK_START_GUIDE = "Quick Start Guide V2.4.0.pdf";
  36. private AnnotationPdfSampleActivityBinding binding;
  37. CAnnotSampleScreenManager screenManager = new CAnnotSampleScreenManager();
  38. private ActivityResultLauncher<Intent> selectDocumentLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
  39. if (result.getData() != null && result.getData().getData() != null) {
  40. Uri uri = result.getData().getData();
  41. CFileUtils.takeUriPermission(this, uri);
  42. binding.pdfView.resetAnnotationType();
  43. binding.pdfView.openPDF(uri);
  44. }
  45. });
  46. @Override
  47. protected void onCreate(Bundle savedInstanceState) {
  48. super.onCreate(savedInstanceState);
  49. binding = AnnotationPdfSampleActivityBinding.inflate(getLayoutInflater());
  50. setContentView(binding.getRoot());
  51. screenManager.bind(binding);
  52. //Extract PDF files from the Android assets folder
  53. initPDFView();
  54. initAnnotationAttributes();
  55. initToolBarView();
  56. initSearchBar();
  57. initAnnotToolbar();
  58. }
  59. private void initPDFView() {
  60. binding.pdfView.setAllowAddAndEditAnnot(true);
  61. CExtractAssetFileTask.extract(this, QUICK_START_GUIDE, QUICK_START_GUIDE, (filePath) ->
  62. binding.pdfView.openPDF(filePath));
  63. resetContextMenu(binding.pdfView, CPreviewMode.Annotation);
  64. binding.pdfView.getCPdfReaderView().setMinScaleEnable(false);
  65. binding.pdfView.addOnPDFFocusedTypeChangeListener(type -> {
  66. if (type != CPDFAnnotation.Type.INK) {
  67. if (binding.inkCtrlView.getVisibility() == View.VISIBLE) {
  68. screenManager.changeWindowStatus(type);
  69. binding.annotationToolBar.updateItemColor();
  70. }
  71. }
  72. });
  73. binding.pdfView.setOnTapMainDocAreaCallback(() -> {
  74. //Use the CFillScreenManager.class to manage fullscreen switching.
  75. screenManager.fillScreenChange();
  76. });
  77. }
  78. /**
  79. * Initialize and set annotation attributes,
  80. * mainly including annotation color, transparency and other attributes
  81. */
  82. private void initAnnotationAttributes() {
  83. initAnnotationAttr(binding.pdfView);
  84. registerAnnotHelper(binding.pdfView);
  85. }
  86. private void initToolBarView() {
  87. binding.pdfToolBar.addMode(CPreviewMode.Annotation);
  88. binding.pdfToolBar.setPreviewModeChangeListener((mode) -> {
  89. binding.pdfToolBar.selectMode(mode);
  90. screenManager.changeWindowStatus(mode);
  91. binding.pdfView.setAllowAddAndEditAnnot(mode != CPreviewMode.Viewer);
  92. binding.pdfView.resetAnnotationType();
  93. resetContextMenu(binding.pdfView, mode);
  94. });
  95. binding.pdfToolBar.setSearchBtnClickListener(v -> {
  96. binding.pdfToolBar.setVisibility(View.GONE);
  97. binding.pdfSearchToolBar.setVisibility(View.VISIBLE);
  98. binding.pdfSearchToolBar.showKeyboard();
  99. });
  100. binding.pdfToolBar.setThumbnailBtnClickListener(v -> {
  101. CPDFBotaDialogFragment dialogFragment = CPDFBotaDialogFragment.newInstance();
  102. dialogFragment.initWithPDFView(binding.pdfView);
  103. CPDFBotaFragmentTabs annotationTab = new CPDFBotaFragmentTabs(CPDFBOTA.THUMBNAIL, getString(R.string.tools_thumbnails));
  104. dialogFragment.setBotaDialogTab(annotationTab);
  105. dialogFragment.show(getSupportFragmentManager(), "ThumbnailList");
  106. });
  107. binding.pdfToolBar.setBoTaBtnClickListener(v -> {
  108. ArrayList<CPDFBotaFragmentTabs> tabs = new ArrayList<>();
  109. CPDFBotaFragmentTabs annotationTab = new CPDFBotaFragmentTabs(CPDFBOTA.ANNOTATION, getString(R.string.tools_annotations));
  110. CPDFBotaFragmentTabs outlineTab = new CPDFBotaFragmentTabs(CPDFBOTA.OUTLINE, getString(R.string.tools_outlines));
  111. CPDFBotaFragmentTabs bookmarkTab = new CPDFBotaFragmentTabs(CPDFBOTA.BOOKMARKS, getString(R.string.tools_bookmarks));
  112. if (binding.pdfToolBar.getMode() == CPreviewMode.Viewer) {
  113. tabs.add(outlineTab);
  114. tabs.add(bookmarkTab);
  115. } else {
  116. tabs.add(outlineTab);
  117. tabs.add(bookmarkTab);
  118. tabs.add(annotationTab);
  119. }
  120. CPDFBotaDialogFragment dialogFragment = CPDFBotaDialogFragment.newInstance();
  121. dialogFragment.initWithPDFView(binding.pdfView);
  122. dialogFragment.setBotaDialogTabs(tabs);
  123. dialogFragment.show(getSupportFragmentManager(), "annotationList");
  124. });
  125. binding.pdfToolBar.setMoreBtnClickListener(v -> {
  126. v.setSelected(true);
  127. //Show the PDF settings dialog fragment
  128. CPopupMenuWindow menuWindow = new CPopupMenuWindow(this);
  129. menuWindow.addItem(R.drawable.tools_ic_preview_settings, R.string.tools_view_setting, v1 -> {
  130. showDisplaySettings(binding.pdfView);
  131. });
  132. menuWindow.addItem(R.drawable.tools_ic_document_info, R.string.tools_document_info, v1 -> {
  133. showDocumentInfo(binding.pdfView);
  134. });
  135. menuWindow.addItem(R.drawable.tools_ic_share, R.string.tools_share, v1 -> {
  136. sharePDF(binding.pdfView);
  137. });
  138. menuWindow.addItem(R.drawable.tools_ic_new_file, R.string.tools_open_document, v1 -> {
  139. if (hasPermissions(STORAGE_PERMISSIONS)) {
  140. selectDocument();
  141. } else {
  142. requestStoragePermissions();
  143. }
  144. });
  145. menuWindow.setOnDismissListener(() -> v.setSelected(false));
  146. menuWindow.showAsDropDown(v);
  147. });
  148. }
  149. private void requestStoragePermissions(){
  150. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU){
  151. startActivity(new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION));
  152. }else {
  153. EasyPermissions.requestPermissions(this, "request permission", REQUEST_EXTERNAL_PERMISSION, STORAGE_PERMISSIONS);
  154. }
  155. }
  156. private void initAnnotToolbar() {
  157. binding.annotationToolBar.initWithPDFView(binding.pdfView);
  158. binding.annotationToolBar.setFragmentManager(getSupportFragmentManager());
  159. binding.annotationToolBar.setAnnotationChangeListener(type -> {
  160. screenManager.changeWindowStatus(type);
  161. //You are required to grant recording permission when selecting voice notes
  162. if (type == CAnnotationType.SOUND) {
  163. if (!EasyPermissions.hasPermissions(this, Manifest.permission.RECORD_AUDIO)) {
  164. EasyPermissions.requestPermissions(this, getString(R.string.tools_use_sound_annot), 111, Manifest.permission.RECORD_AUDIO);
  165. }
  166. }
  167. });
  168. binding.inkCtrlView.initWithPDFView(binding.pdfView);
  169. binding.inkCtrlView.setFragmentManager(getSupportFragmentManager());
  170. }
  171. private void initSearchBar() {
  172. binding.pdfSearchToolBar.initWithPDFView(binding.pdfView);
  173. binding.pdfSearchToolBar.onSearchQueryResults(list -> {
  174. CSearchResultDialogFragment searchResultDialog = new CSearchResultDialogFragment();
  175. searchResultDialog.show(getSupportFragmentManager(), "searchResultDialogFragment");
  176. searchResultDialog.setSearchTextInfos(list);
  177. searchResultDialog.setOnClickSearchItemListener(clickItem -> {
  178. binding.pdfView.getCPdfReaderView().setDisplayPageIndex(clickItem.page);
  179. binding.pdfView.getCPdfReaderView().getTextSearcher().searchBegin(clickItem.page, clickItem.textRangeIndex);
  180. searchResultDialog.dismiss();
  181. });
  182. });
  183. binding.pdfSearchToolBar.setExitSearchListener(() -> {
  184. binding.pdfToolBar.setVisibility(View.VISIBLE);
  185. binding.pdfSearchToolBar.setVisibility(View.GONE);
  186. });
  187. }
  188. private void selectDocument() {
  189. if (!binding.pdfView.getCPdfReaderView().getPDFDocument().hasChanges()) {
  190. selectDocumentLauncher.launch(CFileUtils.getContentIntent());
  191. return;
  192. }
  193. CAlertDialog alertDialog = CAlertDialog.newInstance(getString(com.compdfkit.tools.R.string.tools_save_title), getString(com.compdfkit.tools.R.string.tools_save_message));
  194. alertDialog.setConfirmClickListener(v -> {
  195. //save pdf document
  196. binding.pdfView.savePDF((filePath, pdfUri) -> {
  197. alertDialog.dismiss();
  198. selectDocumentLauncher.launch(CFileUtils.getContentIntent());
  199. });
  200. });
  201. alertDialog.setCancelClickListener(v -> {
  202. alertDialog.dismiss();
  203. selectDocumentLauncher.launch(CFileUtils.getContentIntent());
  204. });
  205. alertDialog.show(getSupportFragmentManager(), "alertDialog");
  206. }
  207. @Override
  208. public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
  209. super.onRequestPermissionsResult(requestCode, permissions, grantResults);
  210. if (requestCode == REQUEST_EXTERNAL_PERMISSION) {
  211. if (EasyPermissions.hasPermissions(this, STORAGE_PERMISSIONS)) {
  212. selectDocument();
  213. }
  214. } else if (requestCode == 111) {
  215. if (!EasyPermissions.hasPermissions(this, permissions)) {
  216. if (EasyPermissions.somePermissionPermanentlyDenied(this, Arrays.asList(permissions))) {
  217. new AppSettingsDialog.Builder(this)
  218. .build().show();
  219. }else {
  220. binding.pdfView.resetAnnotationType();
  221. }
  222. }
  223. } else if (requestCode == AppSettingsDialog.DEFAULT_SETTINGS_REQ_CODE){
  224. if (EasyPermissions.hasPermissions(this, permissions)){
  225. }
  226. }
  227. }
  228. @Override
  229. public void onBackPressed() {
  230. if (binding.pdfView != null) {
  231. binding.pdfView.savePDF((filePath, pdfUri) -> super.onBackPressed());
  232. }
  233. }
  234. }