添加分享,打印,功能。
This commit is contained in:
parent
23e7e8f97b
commit
5323ad1324
@ -66,6 +66,16 @@
|
||||
<data android:scheme="content" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="${applicationId}.fileprovider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/file_paths" />
|
||||
</provider>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@ -0,0 +1,61 @@
|
||||
package com.all.pdfreader.pro.app.ui.adapter
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.os.CancellationSignal
|
||||
import android.os.ParcelFileDescriptor
|
||||
import android.print.PageRange
|
||||
import android.print.PrintAttributes
|
||||
import android.print.PrintDocumentAdapter
|
||||
import android.print.PrintDocumentInfo
|
||||
import java.io.FileOutputStream
|
||||
import java.io.InputStream
|
||||
|
||||
class PrintPdfAdapter(private val context: Context, private val uri: Uri) : PrintDocumentAdapter() {
|
||||
|
||||
override fun onLayout(
|
||||
printAttributes: PrintAttributes?,
|
||||
printAttributes2: PrintAttributes?,
|
||||
cancellationSignal: CancellationSignal,
|
||||
layoutResultCallback: LayoutResultCallback,
|
||||
bundle: Bundle?
|
||||
) {
|
||||
if (cancellationSignal.isCanceled) {
|
||||
layoutResultCallback.onLayoutCancelled()
|
||||
} else {
|
||||
layoutResultCallback.onLayoutFinished(
|
||||
PrintDocumentInfo.Builder("AllPDF")
|
||||
.setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT).build(), true
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onWrite(
|
||||
pageRangeArr: Array<PageRange?>?,
|
||||
parcelFileDescriptor: ParcelFileDescriptor,
|
||||
cancellationSignal: CancellationSignal?,
|
||||
writeResultCallback: WriteResultCallback
|
||||
) {
|
||||
try {
|
||||
val openInputStream: InputStream? = context.contentResolver.openInputStream(uri)
|
||||
val fileOutputStream = FileOutputStream(parcelFileDescriptor.fileDescriptor)
|
||||
val bArr = ByteArray(1024)
|
||||
while (true) {
|
||||
val read = openInputStream?.read(bArr)
|
||||
if (read != null) {
|
||||
if (read > 0) {
|
||||
fileOutputStream.write(bArr, 0, read)
|
||||
} else {
|
||||
writeResultCallback.onWriteFinished(arrayOf(PageRange.ALL_PAGES))
|
||||
openInputStream.close()
|
||||
fileOutputStream.close()
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,20 +1,19 @@
|
||||
package com.all.pdfreader.pro.app.ui.dialog
|
||||
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.all.pdfreader.pro.app.R
|
||||
import com.all.pdfreader.pro.app.databinding.DialogListMoreBinding
|
||||
import com.all.pdfreader.pro.app.room.entity.PdfDocumentEntity
|
||||
import com.all.pdfreader.pro.app.room.repository.PdfRepository
|
||||
import com.all.pdfreader.pro.app.util.AppUtils.dpToPx
|
||||
import com.all.pdfreader.pro.app.util.AppUtils.printPdfFile
|
||||
import com.all.pdfreader.pro.app.util.AppUtils.setClickWithAnimation
|
||||
import com.all.pdfreader.pro.app.util.FileUtils
|
||||
import com.all.pdfreader.pro.app.util.AppUtils.shareFile
|
||||
import com.all.pdfreader.pro.app.util.FileUtils.toFormatFileSize
|
||||
import com.all.pdfreader.pro.app.util.FileUtils.toSlashDate
|
||||
import com.all.pdfreader.pro.app.viewmodel.PdfViewModel
|
||||
@ -22,7 +21,6 @@ import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.resource.bitmap.CenterCrop
|
||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||
import kotlinx.coroutines.launch
|
||||
import java.io.File
|
||||
|
||||
class ListMoreDialogFragment(val filePath: String) : BottomSheetDialogFragment() {
|
||||
@ -97,6 +95,14 @@ class ListMoreDialogFragment(val filePath: String) : BottomSheetDialogFragment()
|
||||
FileDetailsDialogFragment().show(parentFragmentManager, "FileDetailsDialogFragment")
|
||||
dismiss()
|
||||
}
|
||||
binding.shareBtn.setOnClickListener {
|
||||
shareFile(requireActivity(), File(pdfDocument.filePath))
|
||||
dismiss()
|
||||
}
|
||||
binding.printBtn.setOnClickListener {
|
||||
printPdfFile(requireActivity(), Uri.fromFile(File(pdfDocument.filePath)))
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateCollectUi(b: Boolean) {
|
||||
|
||||
@ -2,10 +2,38 @@ package com.all.pdfreader.pro.app.util
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.pdf.PdfRenderer
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.os.CancellationSignal
|
||||
import android.os.ParcelFileDescriptor
|
||||
import android.print.PageRange
|
||||
import android.print.PrintAttributes
|
||||
import android.print.PrintDocumentAdapter
|
||||
import android.print.PrintDocumentInfo
|
||||
import android.print.PrintManager
|
||||
import android.print.pdf.PrintedPdfDocument
|
||||
import android.view.View
|
||||
import android.view.WindowManager
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.webkit.MimeTypeMap
|
||||
import android.webkit.WebView
|
||||
import android.webkit.WebViewClient
|
||||
import android.widget.EditText
|
||||
import android.widget.Toast
|
||||
import androidx.core.content.FileProvider
|
||||
import com.all.pdfreader.pro.app.R
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import androidx.core.graphics.createBitmap
|
||||
import androidx.print.PrintHelper
|
||||
import com.all.pdfreader.pro.app.ui.adapter.PrintPdfAdapter
|
||||
import com.shockwave.pdfium.PdfPasswordException
|
||||
import com.shockwave.pdfium.PdfiumCore
|
||||
import com.tom_roush.pdfbox.pdmodel.common.PDPageLabelRange
|
||||
import java.io.IOException
|
||||
|
||||
object AppUtils {
|
||||
|
||||
@ -62,4 +90,81 @@ object AppUtils {
|
||||
}, 200)
|
||||
}
|
||||
|
||||
/**
|
||||
* 分享文件(自动识别 MIME 类型)
|
||||
* @param context 上下文
|
||||
* @param file 要分享的文件
|
||||
*/
|
||||
fun shareFile(context: Context, file: File) {
|
||||
try {
|
||||
if (!file.exists()) {
|
||||
Toast.makeText(context, context.getString(R.string.error_file_not_exist), Toast.LENGTH_SHORT).show()
|
||||
return
|
||||
}
|
||||
|
||||
val uri: Uri = FileProvider.getUriForFile(
|
||||
context,
|
||||
"${context.packageName}.fileprovider",
|
||||
file
|
||||
)
|
||||
|
||||
val mimeType = getMimeType(file) ?: "*/*"
|
||||
|
||||
val shareIntent = Intent(Intent.ACTION_SEND).apply {
|
||||
type = mimeType
|
||||
putExtra(Intent.EXTRA_STREAM, uri)
|
||||
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
}
|
||||
|
||||
context.startActivity(
|
||||
Intent.createChooser(shareIntent, "share")
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据文件扩展名自动获取 MIME 类型
|
||||
*/
|
||||
private fun getMimeType(file: File): String? {
|
||||
val extension = file.extension.lowercase()
|
||||
return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension)
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印PDF,传入uri
|
||||
*/
|
||||
fun printPdfFile(context: Context, uri: Uri?) {
|
||||
try {
|
||||
PdfiumCore(context).newDocument(
|
||||
context.contentResolver.openFileDescriptor(
|
||||
uri!!,
|
||||
PDPageLabelRange.STYLE_ROMAN_LOWER
|
||||
)
|
||||
)
|
||||
if (PrintHelper.systemSupportsPrint()) {
|
||||
val printManager =
|
||||
context.getSystemService(Context.PRINT_SERVICE) as PrintManager
|
||||
val str = context.getString(R.string.app_name) + " Document"
|
||||
printManager.print(
|
||||
str,
|
||||
PrintPdfAdapter(context, uri),
|
||||
null as PrintAttributes?
|
||||
)
|
||||
return
|
||||
}
|
||||
Toast.makeText(context, R.string.device_does_not_support_printing, Toast.LENGTH_LONG).show()
|
||||
} catch (e: PdfPasswordException) {
|
||||
Toast.makeText(context, R.string.pdf_cant_print_password_protected, Toast.LENGTH_LONG).show()
|
||||
e.printStackTrace()
|
||||
} catch (e2: IOException) {
|
||||
Toast.makeText(context, R.string.cannot_print_malformed_pdf, Toast.LENGTH_LONG).show()
|
||||
e2.printStackTrace()
|
||||
} catch (e3: java.lang.Exception) {
|
||||
Toast.makeText(context, R.string.pdf_cannot_print_error, Toast.LENGTH_LONG).show()
|
||||
e3.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -274,47 +274,6 @@ class PdfScanner(
|
||||
return TimeUnit.MILLISECONDS.toHours(System.currentTimeMillis() - lastScan)
|
||||
}
|
||||
|
||||
|
||||
// private fun generateFastThumbnail(context: Context, pdfFile: File): String? {
|
||||
// return try {
|
||||
// val fileDescriptor =
|
||||
// ParcelFileDescriptor.open(pdfFile, ParcelFileDescriptor.MODE_READ_ONLY)
|
||||
// val pdfRenderer = PdfRenderer(fileDescriptor)
|
||||
//
|
||||
// if (pdfRenderer.pageCount > 0) {
|
||||
// val page = pdfRenderer.openPage(0)
|
||||
// // 创建 Bitmap
|
||||
// val bitmap = createBitmap(page.width, page.height)
|
||||
// val canvas = Canvas(bitmap)
|
||||
// canvas.drawColor(Color.WHITE) // 填充白色背景
|
||||
//
|
||||
// page.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY)
|
||||
// page.close()
|
||||
//
|
||||
// // 保存到缓存目录
|
||||
// val cacheDir = File(context.cacheDir, "thumbnails")
|
||||
// if (!cacheDir.exists()) cacheDir.mkdirs()
|
||||
// val thumbFile = File(cacheDir, pdfFile.nameWithoutExtension + ".jpg")
|
||||
//
|
||||
// FileOutputStream(thumbFile).use { out ->
|
||||
// bitmap.compress(Bitmap.CompressFormat.JPEG, 80, out)
|
||||
// }
|
||||
//
|
||||
// pdfRenderer.close()
|
||||
// fileDescriptor.close()
|
||||
//
|
||||
// thumbFile.absolutePath
|
||||
// } else {
|
||||
// pdfRenderer.close()
|
||||
// fileDescriptor.close()
|
||||
// null
|
||||
// }
|
||||
// } catch (e: Exception) {
|
||||
// e.printStackTrace()
|
||||
// null
|
||||
// }
|
||||
// }
|
||||
|
||||
private fun generateFastThumbnail(
|
||||
context: Context,
|
||||
pdfFile: File,
|
||||
|
||||
@ -169,6 +169,7 @@
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/shareBtn"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
@ -191,6 +192,7 @@
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/printBtn"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
|
||||
@ -84,4 +84,8 @@
|
||||
<string name="last_modified">Last Modified</string>
|
||||
<string name="last_viewed">Last Viewed</string>
|
||||
<string name="size">Size</string>
|
||||
<string name="device_does_not_support_printing">Your device does not support printing</string>
|
||||
<string name="pdf_cant_print_password_protected">Cannot print a password protected PDF file</string>
|
||||
<string name="cannot_print_malformed_pdf">Cannot print a malformed PDF file</string>
|
||||
<string name="pdf_cannot_print_error">Cannot print PDF file, Unknown error has occurred</string>
|
||||
</resources>
|
||||
7
app/src/main/res/xml/file_paths.xml
Normal file
7
app/src/main/res/xml/file_paths.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<paths xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- 允许分享外部存储中的文件 -->
|
||||
<external-path
|
||||
name="external_files"
|
||||
path="." />
|
||||
</paths>
|
||||
Loading…
Reference in New Issue
Block a user