This commit is contained in:
ocean 2025-12-16 14:00:03 +08:00
parent 3ad4c5e916
commit 544fe96be5
12 changed files with 234 additions and 82 deletions

View File

@ -150,6 +150,12 @@
android:label="@string/app_name" android:label="@string/app_name"
android:screenOrientation="portrait" /> android:screenOrientation="portrait" />
<activity
android:name=".ui.act.PictureSelectorCameraActivity"
android:exported="true"
android:label="@string/app_name"
android:screenOrientation="portrait" />
<provider <provider
android:name="androidx.core.content.FileProvider" android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider" android:authorities="${applicationId}.fileprovider"

View File

@ -29,6 +29,13 @@ class AdInstShower(
val errorMsg = "广告展示过于频繁, 请等待 ${(SHOW_INTERVAL - (now - lastShowTimestamp)) / 1000}s间隔限制60s" val errorMsg = "广告展示过于频繁, 请等待 ${(SHOW_INTERVAL - (now - lastShowTimestamp)) / 1000}s间隔限制60s"
showListener?.onAdShowFailed(errorMsg) showListener?.onAdShowFailed(errorMsg)
Log.d(AdsInsUtil.Placement.TAG, "showAd->$errorMsg") Log.d(AdsInsUtil.Placement.TAG, "showAd->$errorMsg")
AnalyticsUtils.logAdEvent(
placement,
AnalyticsUtils.AdEvent.SHOW_FAIL_ME,
1001,
errorMsg
)
return return
} }
} }
@ -38,6 +45,13 @@ class AdInstShower(
val errorMsg = "插页式广告缓存为空 = $placement" val errorMsg = "插页式广告缓存为空 = $placement"
showListener?.onAdShowFailed(errorMsg) showListener?.onAdShowFailed(errorMsg)
Log.d(AdsInsUtil.Placement.TAG, "showAd->$errorMsg") Log.d(AdsInsUtil.Placement.TAG, "showAd->$errorMsg")
AnalyticsUtils.logAdEvent(
placement,
AnalyticsUtils.AdEvent.SHOW_FAIL_ME,
1002,
errorMsg
)
return return
} }

View File

@ -489,6 +489,7 @@ class PdfViewActivity : BaseActivity(), OnLoadCompleteListener, OnPageChangeList
setSelection(0) setSelection(0)
} }
} else { } else {
AnalyticsUtils.logEvent(AnalyticsUtils.Event.PDFTO_HOME_CK)
AdsInsUtil.showFinishAd( AdsInsUtil.showFinishAd(
this@PdfViewActivity, this@PdfViewActivity,
AdsInsUtil.AdPlacement.INT_AND_PDFTOHOME AdsInsUtil.AdPlacement.INT_AND_PDFTOHOME

View File

@ -1,11 +1,9 @@
package com.all.pdfreader.pdf.reader.ui.act package com.all.pdfreader.pdf.reader.ui.act
import android.content.Context
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.fragment.app.Fragment
import com.all.pdfreader.pdf.reader.PRApp import com.all.pdfreader.pdf.reader.PRApp
import com.all.pdfreader.pdf.reader.R import com.all.pdfreader.pdf.reader.R
import com.all.pdfreader.pdf.reader.databinding.ActPictureSelectorBinding import com.all.pdfreader.pdf.reader.databinding.ActPictureSelectorBinding
@ -18,8 +16,6 @@ import com.luck.picture.lib.config.SelectMimeType
import com.luck.picture.lib.config.SelectModeConfig import com.luck.picture.lib.config.SelectModeConfig
import com.luck.picture.lib.engine.CompressFileEngine import com.luck.picture.lib.engine.CompressFileEngine
import com.luck.picture.lib.entity.LocalMedia import com.luck.picture.lib.entity.LocalMedia
import com.luck.picture.lib.interfaces.OnKeyValueResultCallbackListener
import com.luck.picture.lib.interfaces.OnMediaEditInterceptListener
import com.luck.picture.lib.interfaces.OnResultCallbackListener import com.luck.picture.lib.interfaces.OnResultCallbackListener
import com.luck.picture.lib.style.PictureSelectorStyle import com.luck.picture.lib.style.PictureSelectorStyle
import com.luck.picture.lib.style.SelectMainStyle import com.luck.picture.lib.style.SelectMainStyle
@ -64,58 +60,47 @@ class PictureSelectorActivity : BaseActivity() {
.setSelectionMode(SelectModeConfig.MULTIPLE) .setSelectionMode(SelectModeConfig.MULTIPLE)
.setMaxSelectNum(50) .setMaxSelectNum(50)
.isPreviewFullScreenMode(false) .isPreviewFullScreenMode(false)
.setCompressEngine(object : CompressFileEngine { .setCompressEngine(CompressFileEngine { context, source, call ->
override fun onStartCompress( Luban.with(context)
context: Context?, .load(source)
source: ArrayList<Uri?>?, .ignoreBy(100)
call: OnKeyValueResultCallbackListener? .setCompressListener(object : OnNewCompressListener {
) { override fun onStart() {
Luban.with(context)
.load(source)
.ignoreBy(100)
.setCompressListener(object : OnNewCompressListener {
override fun onStart() {
} }
override fun onSuccess( override fun onSuccess(
source: String?, source: String?,
compressFile: File? compressFile: File?
) { ) {
call?.onCallback(source, compressFile?.absolutePath) call?.onCallback(source, compressFile?.absolutePath)
} }
override fun onError(source: String?, e: Throwable?) { override fun onError(source: String?, e: Throwable?) {
call?.onCallback(source, null) call?.onCallback(source, null)
} }
}) })
.launch() .launch()
}
}) })
.setEditMediaInterceptListener(object : OnMediaEditInterceptListener { .setEditMediaInterceptListener { fragment, currentLocalMedia, requestCode ->
override fun onStartMediaEdit( val currentEditPath = currentLocalMedia.getAvailablePath()
fragment: Fragment, currentLocalMedia: LocalMedia, requestCode: Int val inputUri = if (PictureMimeType.isContent(currentEditPath)) {
) { currentEditPath.toUri()
val currentEditPath = currentLocalMedia.getAvailablePath() } else {
val inputUri = if (PictureMimeType.isContent(currentEditPath)) { Uri.fromFile(File(currentEditPath))
currentEditPath.toUri()
} else {
Uri.fromFile(File(currentEditPath))
}
val destinationUri = Uri.fromFile(
File(
getSandboxPath(), DateUtils.getCreateFileName("CROP_") + ".jpeg"
)
)
val uCrop = UCrop.of<Any>(inputUri, destinationUri)
val buildOptions = UCrop.Options().apply {
isDarkStatusBarBlack(true)
}
uCrop.withOptions(buildOptions)
uCrop.start(this@PictureSelectorActivity, fragment, requestCode)
} }
val destinationUri = Uri.fromFile(
}).buildLaunch(R.id.fragment_container,object : OnResultCallbackListener<LocalMedia>{ File(
getSandboxPath(), DateUtils.getCreateFileName("CROP_") + ".jpeg"
)
)
val uCrop = UCrop.of<Any>(inputUri, destinationUri)
val buildOptions = UCrop.Options().apply {
isDarkStatusBarBlack(true)
}
uCrop.withOptions(buildOptions)
uCrop.start(this@PictureSelectorActivity, fragment, requestCode)
}.buildLaunch(R.id.fragment_container,object : OnResultCallbackListener<LocalMedia>{
override fun onResult(result: ArrayList<LocalMedia>) { override fun onResult(result: ArrayList<LocalMedia>) {
logDebug("forResult ->${result.size}") logDebug("forResult ->${result.size}")
if (result.isNotEmpty()) { if (result.isNotEmpty()) {

View File

@ -0,0 +1,88 @@
package com.all.pdfreader.pdf.reader.ui.act
import android.os.Bundle
import android.view.View
import com.all.pdfreader.pdf.reader.R
import com.all.pdfreader.pdf.reader.databinding.ActPictureSelectorBinding
import com.all.pdfreader.pdf.reader.model.PdfPickerSource
import com.all.pdfreader.pdf.reader.util.AnalyticsUtils
import com.luck.picture.lib.basic.PictureSelector
import com.luck.picture.lib.config.SelectMimeType
import com.luck.picture.lib.engine.CompressFileEngine
import com.luck.picture.lib.entity.LocalMedia
import com.luck.picture.lib.interfaces.OnResultCallbackListener
import top.zibin.luban.Luban
import top.zibin.luban.OnNewCompressListener
import java.io.File
class PictureSelectorCameraActivity : BaseActivity() {
private lateinit var binding: ActPictureSelectorBinding
override val rootBottomView: View
get() = binding.rootBottomLayout
override val TAG = "PictureSelectorCameraActivity"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActPictureSelectorBinding.inflate(layoutInflater)
setContentView(binding.root)
AnalyticsUtils.logEvent(AnalyticsUtils.Event.SCAN_TO_PDF_SHOW)
setupImmersionBar {
statusBarView(binding.view)
statusBarDarkFont(false)
}
openImagePicker()
}
private fun openImagePicker() {
PictureSelector.create(this)
.openCamera(SelectMimeType.ofImage())
.setCompressEngine(CompressFileEngine { context, source, call ->
Luban.with(context)
.load(source)
.ignoreBy(100)
.setCompressListener(object : OnNewCompressListener {
override fun onStart() {
}
override fun onSuccess(
source: String?,
compressFile: File?
) {
call?.onCallback(source, compressFile?.absolutePath)
}
override fun onError(source: String?, e: Throwable?) {
call?.onCallback(source, null)
}
})
.launch()
})
.buildLaunch(R.id.fragment_container, object : OnResultCallbackListener<LocalMedia> {
override fun onResult(result: ArrayList<LocalMedia>) {
logDebug("forResult ->${result.size}")
if (result.isNotEmpty()) {
// result 中可能有带裁剪的 Uri 或原图 Uri
// 取出路径列表
val paths = result.mapNotNull { media ->
media.availablePath
}
if (paths.isEmpty()) {
return
}
val intent = PdfResultActivity.createIntentInputFile(
this@PictureSelectorCameraActivity,
ArrayList(paths),
PdfPickerSource.IMAGES_TO_PDF
)
startActivity(intent)
finish()
}
}
override fun onCancel() {
finish()
}
})
}
}

View File

@ -9,6 +9,7 @@ import com.all.pdfreader.pdf.reader.databinding.FragmentToolsBinding
import com.all.pdfreader.pdf.reader.model.PdfPickerSource import com.all.pdfreader.pdf.reader.model.PdfPickerSource
import com.all.pdfreader.pdf.reader.ui.act.PdfPickerActivity import com.all.pdfreader.pdf.reader.ui.act.PdfPickerActivity
import com.all.pdfreader.pdf.reader.ui.act.PictureSelectorActivity import com.all.pdfreader.pdf.reader.ui.act.PictureSelectorActivity
import com.all.pdfreader.pdf.reader.ui.act.PictureSelectorCameraActivity
class ToolsFrag : BaseFrag() { class ToolsFrag : BaseFrag() {
override val TAG: String = "ToolsFrag" override val TAG: String = "ToolsFrag"
@ -59,5 +60,9 @@ class ToolsFrag : BaseFrag() {
val intent = PdfPickerActivity.createIntent(requireActivity(), PdfPickerSource.PRINT) val intent = PdfPickerActivity.createIntent(requireActivity(), PdfPickerSource.PRINT)
startActivity(intent) startActivity(intent)
} }
binding.scanToPdfBtn.setOnClickListener {
val intent = Intent(requireActivity(), PictureSelectorCameraActivity::class.java)
startActivity(intent)
}
} }
} }

View File

@ -96,6 +96,10 @@ object AnalyticsUtils {
const val UNLOCK_SUCCESS = "unlock_success" // 解锁成功unlock_success const val UNLOCK_SUCCESS = "unlock_success" // 解锁成功unlock_success
const val KEEP_SCREEN_OPEN = "keep_screen_open" // 点击打开keep_screen_open const val KEEP_SCREEN_OPEN = "keep_screen_open" // 点击打开keep_screen_open
const val KEEP_SCREEN_CLOSE = "keep_screen_close" // 点击关闭keep_screen_close const val KEEP_SCREEN_CLOSE = "keep_screen_close" // 点击关闭keep_screen_close
const val SHARE = "share"//所有分享文件的操作
const val PRINT = "print"//所有打印
const val PDFTO_HOME_CK = "pdfto_home_ck"//pdf阅读页响应返回
const val SCAN_TO_PDF_SHOW = "scan_to_pdf_show" //扫描成pdf功能界面
} }
/** param 常量(可扩展) */ /** param 常量(可扩展) */
@ -112,6 +116,7 @@ object AnalyticsUtils {
LOAD_FAIL("load_fail_header"), LOAD_FAIL("load_fail_header"),
SHOW_SUC("show_suc_header"), SHOW_SUC("show_suc_header"),
SHOW_FAIL("show_fail_header"), SHOW_FAIL("show_fail_header"),
SHOW_FAIL_ME("show_fail_me_header"),//记录自定义的错误信息
} }
/** 统一广告打点 */ /** 统一广告打点 */

View File

@ -115,6 +115,7 @@ object AppUtils {
* @param file 要分享的文件 * @param file 要分享的文件
*/ */
fun shareFile(context: Context, file: File) { fun shareFile(context: Context, file: File) {
AnalyticsUtils.logEvent(AnalyticsUtils.Event.SHARE)
try { try {
if (!file.exists()) { if (!file.exists()) {
ToastUtils.show(context, context.getString(R.string.error_file_not_exist)) ToastUtils.show(context, context.getString(R.string.error_file_not_exist))
@ -150,6 +151,7 @@ object AppUtils {
* @param files 要分享的文件列表 * @param files 要分享的文件列表
*/ */
fun shareMultipleFiles(context: Context, files: List<File>) { fun shareMultipleFiles(context: Context, files: List<File>) {
AnalyticsUtils.logEvent(AnalyticsUtils.Event.SHARE)
try { try {
if (files.isEmpty()) { if (files.isEmpty()) {
ToastUtils.show(context, context.getString(R.string.error_file_not_exist)) ToastUtils.show(context, context.getString(R.string.error_file_not_exist))
@ -214,6 +216,7 @@ object AppUtils {
* @return PrintResult 打印结果的状态成功密码保护设备不支持等 * @return PrintResult 打印结果的状态成功密码保护设备不支持等
*/ */
fun printPdfFile(context: Context, uri: Uri?): PrintResult { fun printPdfFile(context: Context, uri: Uri?): PrintResult {
AnalyticsUtils.logEvent(AnalyticsUtils.Event.PRINT)
return try { return try {
// 打开文件描述符,用于访问 PDF 文件内容 // 打开文件描述符,用于访问 PDF 文件内容
val pd = context.contentResolver.openFileDescriptor( val pd = context.contentResolver.openFileDescriptor(

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="20dp"/>
<solid android:color="#F5FFF3"/>
</shape>

View File

@ -0,0 +1,34 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="30dp"
android:height="30dp"
android:viewportWidth="30"
android:viewportHeight="30">
<group>
<clip-path
android:pathData="M0,0h30v30h-30z"/>
<path
android:pathData="M0.833,10V1.98C0.834,1.676 0.955,1.385 1.169,1.17C1.384,0.955 1.675,0.834 1.979,0.833H10V3.125H3.124V10H0.833Z"
android:fillColor="#77FF00"/>
<path
android:pathData="M19.167,3.125H26.666V10H29.167V1.98C29.166,1.676 29.034,1.384 28.8,1.169C28.565,0.954 28.247,0.833 27.915,0.833H19.167V3.125Z"
android:fillColor="#77FF00"/>
<path
android:pathData="M26.666,20V26.876H19.167V29.167H27.921C28.253,29.165 28.57,29.042 28.804,28.826C29.037,28.61 29.168,28.318 29.167,28.014V20H26.666Z"
android:fillColor="#77FF00"/>
<path
android:pathData="M10,26.882H3.124V20H0.833V28.02C0.834,28.324 0.955,28.615 1.17,28.83C1.384,29.045 1.675,29.166 1.979,29.167H10V26.882Z"
android:fillColor="#77FF00"/>
<path
android:pathData="M29.167,14.167H23.333V15.834H29.167V14.167Z"
android:fillColor="#77FF00"/>
<path
android:pathData="M7.5,14.167H0.833V15.834H7.5V14.167Z"
android:fillColor="#77FF00"/>
<path
android:pathData="M22.779,12.5H23.333V8.616C23.333,8.099 23.119,7.603 22.738,7.238C22.357,6.872 21.841,6.667 21.302,6.667H9.528C8.99,6.668 8.474,6.874 8.094,7.239C7.714,7.605 7.5,8.1 7.5,8.616V12.5H22.779Z"
android:fillColor="#77FF00"/>
<path
android:pathData="M22.779,14.167H7.5V22.178C7.5,22.439 7.553,22.698 7.655,22.939C7.757,23.181 7.906,23.4 8.095,23.585C8.284,23.77 8.508,23.916 8.754,24.016C9.001,24.116 9.265,24.167 9.531,24.167H21.302C21.569,24.167 21.833,24.116 22.079,24.016C22.326,23.916 22.55,23.77 22.738,23.585C22.927,23.4 23.076,23.181 23.179,22.939C23.281,22.698 23.333,22.439 23.333,22.178V14.167H22.779Z"
android:fillColor="#77FF00"/>
</group>
</vector>

View File

@ -117,6 +117,37 @@
android:layout_marginBottom="16dp" android:layout_marginBottom="16dp"
android:orientation="horizontal"> android:orientation="horizontal">
<LinearLayout
android:id="@+id/scanToPdfBtn"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<LinearLayout
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@drawable/drw_tools_scan_bg"
android:gravity="center">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/tools_scan_to_pdf_img" />
</LinearLayout>
<TextView
style="@style/TextViewFont_PopMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="@string/scan_to_pdf"
android:textColor="@color/text_color_lv1"
android:textSize="12sp" />
</LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/mergeBtn" android:id="@+id/mergeBtn"
android:layout_width="0dp" android:layout_width="0dp"
@ -177,35 +208,6 @@
android:textSize="12sp" /> android:textSize="12sp" />
</LinearLayout> </LinearLayout>
<LinearLayout
android:id="@+id/printBtn"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<LinearLayout
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@drawable/drw_tools_print_bg"
android:gravity="center">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/tools_print" />
</LinearLayout>
<TextView
style="@style/TextViewFont_PopMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="@string/print_pdf"
android:textColor="@color/text_color_lv1"
android:textSize="12sp" />
</LinearLayout>
</LinearLayout> </LinearLayout>
@ -277,12 +279,12 @@
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/printBtn"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="1"
android:gravity="center" android:gravity="center"
android:orientation="vertical" android:orientation="vertical">
android:visibility="invisible">
<LinearLayout <LinearLayout
android:layout_width="60dp" android:layout_width="60dp"

View File

@ -197,4 +197,5 @@
<string name="processing_failed">Processing failed</string> <string name="processing_failed">Processing failed</string>
<string name="tap_again_to_exit">Tap again to exit</string> <string name="tap_again_to_exit">Tap again to exit</string>
<string name="ad_attribution" translatable="false">Ad</string> <string name="ad_attribution" translatable="false">Ad</string>
<string name="scan_to_pdf">Scan to PDF</string>
</resources> </resources>