首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >保存PDF以使用具有向后兼容性的iText进行共享

保存PDF以使用具有向后兼容性的iText进行共享
EN

Stack Overflow用户
提问于 2022-02-10 02:09:35
回答 1查看 241关注 0票数 0

在Android上保存PDF文件的一个问题已经困扰了我几周了,我做的每一个Google搜索都会产生一个紫色链接列表。

我尝试过许多方法,但只使用内置的PDF创建者来保存PDF文件,这并不能达到我的目的。

我有很多问题要回答,希望你们中的一些人能帮上忙。

问题1:您应该在哪里保存要共享的PDF文件,然后在后面立即删除?

Q1 a)是必需的ContentResolver & ContentProvider,还是只有在应用程序之间共享“目录”时才会这样做?

从直觉上讲,我最有意义的做法是将PDF保存在内部缓存目录中,然后从那里共享它,然后删除它。

问题2:存储具有向后兼容性的文件的方法是什么?

据我所读,不同的SDK级别需要不同的文件存储方法,即:

  • <= SDK 28使用传统的存储方法,即(使用File )?
  • 如果使用外部存储,则应请求<= SDK 29对遗留存储的权限。
  • = SDK 30 Android强制作用域存储

使用SAF (Storage )似乎是用来存储像PDF这样的文档的推荐方式。但是,当用户只是生成和共享PDF时,我不打算向用户显示文件选择器。

我遇到了这个非常普通的异常,它发生在iText关闭输出流时。下面是一些代码示例及其产生的错误。

SDK 30文件API测试

代码语言:javascript
运行
复制
fun createPdfInternalSDK30(context: Context) {
    val fileName = "test.pdf"

    //  MODE_PRIVATE creates in internal storage, right?
    val out = context.openFileOutput(fileName, Context.MODE_PRIVATE)
    // out path: /data/user/0/dk.overlevelsesguiden.de10her/files/test.pdf

    try {
        val writer = PdfWriter(out)
        val pdf = PdfDocument(writer)
        
        Document(pdf, PageSize.A4, false).apply { 
            add(Paragraph("Test"))
            close()
        }
    } catch (e: IOException) {
        e.printStackTrace()
    }
}

误差

代码语言:javascript
运行
复制
java.lang.ExceptionInInitializerError
        at com.itextpdf.commons.actions.producer.ProducerBuilder.modifyProducer(ProducerBuilder.java:97)
        at com.itextpdf.kernel.actions.events.FlushPdfDocumentEvent.doAction(FlushPdfDocumentEvent.java:103)
        at com.itextpdf.commons.actions.EventManager.onEvent(EventManager.java:71)
        at com.itextpdf.kernel.pdf.PdfDocument.close(PdfDocument.java:849)
        at com.itextpdf.layout.Document.close(Document.java:117)
        at dk.overlevelsesguiden.de10her.business.PDFService.createPdfInternalSDK30(PDFService.kt:118)
    Caused by: java.util.regex.PatternSyntaxException: Syntax error in regexp pattern near index 12
        \$\{([^}]*)}

SDK 29+作用域存储测试

代码语言:javascript
运行
复制
    @RequiresApi(api = Build.VERSION_CODES.Q)
    fun createPdfSharedSDK29plus(context: Context) {
        val pdfCollection = MediaStore.Downloads.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)

        val contentValues = ContentValues().apply {
            put(MediaStore.MediaColumns.DISPLAY_NAME, "title")
            put(MediaStore.MediaColumns.MIME_TYPE, "application/pdf")
        }

        var uri: Uri? = null

        try {
            uri = context.contentResolver.insert(pdfCollection, contentValues) ?: throw IOException("Failed to create new MediaStore record")
            val out = context.contentResolver.openOutputStream(uri)
            val writer = PdfWriter(out)
            val pdf = PdfDocument(writer)
            Document(pdf, PageSize.A4, false).apply {
                add(Paragraph("Test"))
                close()
            }
        } catch (e: IOException) {
            uri?.let { orphanUri ->
                context.contentResolver.delete(orphanUri, null, null)
            }
        }
    }

误差

代码语言:javascript
运行
复制
java.lang.ExceptionInInitializerError
        at com.itextpdf.commons.actions.producer.ProducerBuilder.modifyProducer(ProducerBuilder.java:97)
        at com.itextpdf.kernel.actions.events.FlushPdfDocumentEvent.doAction(FlushPdfDocumentEvent.java:103)
        at com.itextpdf.commons.actions.EventManager.onEvent(EventManager.java:71)
        at com.itextpdf.kernel.pdf.PdfDocument.close(PdfDocument.java:849)
        at com.itextpdf.layout.Document.close(Document.java:117)
        at dk.overlevelsesguiden.de10her.business.PDFService.finalTest(PDFService.kt:118)
    Caused by: java.util.regex.PatternSyntaxException: Syntax error in regexp pattern near index 12
        \$\{([^}]*)}

声明权限

代码语言:javascript
运行
复制
<!-- Without this folders will be inaccessible in Android-11 and above devices -->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
    
<!-- Without this entry storage-permission entry will not be visible under app-info permissions list Android-10 and below -->
<uses-permission 
    android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    android:maxSdkVersion="28"
/>
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-02-10 10:29:11

你提出了很多问题。这个答案集中在您所显示的实际错误上。

所显示的实际错误都会导致

代码语言:javascript
运行
复制
java.util.regex.PatternSyntaxException: Syntax error in regexp pattern near index 12
        \$\{([^}]*)}

在iText类ProducerBuilder的初始化过程中。这种情况发生在这里:

代码语言:javascript
运行
复制
private static final String PATTERN_STRING = "\\$\\{([^}]*)}";
private static final Pattern PATTERN = Pattern.compile(PATTERN_STRING);

实际上,JREs中的正则表达式与Android中的正则表达式不同。在普通Java中,正则表达式\$\{([^}]*)}被接受,如果以前没有未转义的打开{,则表示字符的}不需要转义。另一方面,Android要求它即使在那时也要逃脱。

昨天已经提交了解决此问题的方法-- https://github.com/itext/itext7/commit/32bf2552770866dce4516798e7b11f26631ae92f --模式字符串现在是:

代码语言:javascript
运行
复制
private static final String PATTERN_STRING = "\\$\\{([^}]*)\\}";

因此,在下一个iText发行版(或在真正的当前快照中)中,这个错误将不再发生。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71058982

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档