Commit d624bb30 authored by wanglei's avatar wanglei

...

parent 1091d128
1.Vision识别文本
[ML Kit Vision 快速入门示例应用](https://github.com/googlesamples/mlkit/tree/master/android/vision-quickstart)
2.文档扫描
[文档扫描器](https://developers.google.com/ml-kit/vision/doc-scanner/android?hl=zh-cn)
\ No newline at end of file
......@@ -50,11 +50,6 @@ dependencies {
implementation(libs.material)
implementation(libs.androidx.activity)
implementation(libs.androidx.constraintlayout)
implementation(libs.androidx.navigation.fragment.ktx)
implementation(libs.androidx.navigation.ui.ktx)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
//第三方UI
implementation("io.github.cymchad:BaseRecyclerViewAdapterHelper4:4.1.4")
......@@ -64,6 +59,8 @@ dependencies {
//Pdf库
implementation("com.tom-roush:pdfbox-android:2.0.27.0")
api(project(":android-pdf-viewer"))
//Word库
......
......@@ -7,6 +7,7 @@
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<application
android:name=".helper.MyApplication"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
......@@ -45,7 +46,7 @@
android:screenOrientation="portrait"
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<activity
android:name=".ui.pdf.PdfActivity"
android:name=".ui.document.pdf.PdfActivity"
android:exported="false"
android:screenOrientation="portrait"
android:theme="@style/Theme.PDFViewerScannerWhite"
......
......@@ -2,7 +2,8 @@ package com.base.pdfviewerscannerwhite.bean
data class DocumentBean(
val path: String = "",
val type: String = ""
val type: String = "",
var isBookmarked: Boolean = false
) {
companion object {
......
package com.base.pdfviewerscannerwhite.helper
import android.app.Activity
import android.app.Application
import android.text.TextUtils
import com.base.pdfviewerscannerwhite.utils.AppPreferences
import com.base.pdfviewerscannerwhite.utils.LogEx
import java.util.UUID
class MyApplication : Application() {
private val TAG = "MyApplication"
var uuid = ""
companion object {
lateinit var context: MyApplication
@JvmField
var PAUSED_VALUE = 0
}
override fun onCreate() {
super.onCreate()
context = this
initUUid()
initApp()
}
private fun initUUid() {
//使用同一个uuid来测试上报
//7a6f8e5f-ca67-4149-975b-dacdc6c51aff1723174621132
// AppPreferences.getInstance().put("uuid", "7a6f8e5f-ca67-4149-975b-dacdc6c51aff1723174621132")
uuid = AppPreferences.getInstance().getString("uuid", "")
if (TextUtils.isEmpty(uuid)) {
uuid = UUID.randomUUID().toString()
// + System.currentTimeMillis()
AppPreferences.getInstance().put("uuid", uuid)
LogEx.logDebug(TAG, "uuid=$uuid")
}
}
fun initApp() {
}
}
\ No newline at end of file
......@@ -18,6 +18,10 @@ import java.io.File
class DocumentAdapter : BaseQuickAdapter<DocumentBean, DocumentAdapter.DocumentViewHolder>() {
inner class DocumentViewHolder(view: View) : ViewHolder(view)
var itemClick: ((path: String) -> Unit)? = null
var bookmarkAction: ((addRemove: Boolean, path: String) -> Unit)? = null
@SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder: DocumentViewHolder, position: Int, item: DocumentBean?) {
if (item == null) return
......@@ -28,6 +32,24 @@ class DocumentAdapter : BaseQuickAdapter<DocumentBean, DocumentAdapter.DocumentV
val file = File(item.path)
binding.tvName.text = file.name
binding.tvInfo.text = file.lastModified().toFormatTime() + " " + file.length().toFormatSize()
if (item.isBookmarked) {
binding.ivBookmark.setImageResource(R.mipmap.h_soucang_s)
} else {
binding.ivBookmark.setImageResource(R.mipmap.h_soucang_n)
}
binding.flBookmark.setOnClickListener {
if (item.isBookmarked) {
bookmarkAction?.invoke(false, item.path)
} else {
bookmarkAction?.invoke(true, item.path)
}
item.isBookmarked = !item.isBookmarked
notifyItemChanged(position, "aaaa")
}
binding.root.setOnClickListener {
itemClick?.invoke(item.path)
}
}
override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): DocumentViewHolder {
......
package com.base.pdfviewerscannerwhite.ui.pdf
package com.base.pdfviewerscannerwhite.ui.document
import android.content.Intent
import androidx.lifecycle.lifecycleScope
import com.base.pdfviewerscannerwhite.bean.ConstObject
import com.base.pdfviewerscannerwhite.bean.DocumentBean
import com.base.pdfviewerscannerwhite.bean.DocumentBean.Companion.TYPE_PDF
import com.base.pdfviewerscannerwhite.databinding.FragmentPdfBinding
import com.base.pdfviewerscannerwhite.databinding.FragmentDocumentBinding
import com.base.pdfviewerscannerwhite.helper.BaseFragment
import com.base.pdfviewerscannerwhite.ui.adapter.DocumentAdapter
import com.base.pdfviewerscannerwhite.ui.document.pdf.PdfActivity
import com.base.pdfviewerscannerwhite.utils.PermissionUtils.checkStorePermission
import com.base.pdfviewerscannerwhite.utils.SpStringUtils
import com.base.pdfviewerscannerwhite.utils.SpStringUtils.BOOKMARK_KEY
import com.base.pdfviewerscannerwhite.utils.getMediaFile
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.File
class PdfFragment() : BaseFragment<FragmentPdfBinding>() {
class DocumentFragment() : BaseFragment<FragmentDocumentBinding>() {
private var type = TYPE_PDF
private var documentList: List<DocumentBean>? = null
......@@ -23,13 +28,12 @@ class PdfFragment() : BaseFragment<FragmentPdfBinding>() {
this.type = type
}
override val binding: FragmentPdfBinding by lazy {
FragmentPdfBinding.inflate(layoutInflater)
override val binding: FragmentDocumentBinding by lazy {
FragmentDocumentBinding.inflate(layoutInflater)
}
override fun setView() {
adapter = DocumentAdapter()
binding.rv.adapter = adapter
initAdapter()
if (documentList != null) {
adapter.submitList(documentList)
......@@ -41,15 +45,56 @@ class PdfFragment() : BaseFragment<FragmentPdfBinding>() {
}
private fun initAdapter() {
adapter = DocumentAdapter()
adapter.bookmarkAction = { addRemove, path ->
if (addRemove) {
SpStringUtils.addSpString(BOOKMARK_KEY, path)
} else {
SpStringUtils.deleteSpString(BOOKMARK_KEY, path)
}
}
adapter.itemClick = { path ->
startActivity(Intent(requireContext(), PdfActivity::class.java).apply {
putExtra("path", path)
})
}
binding.rv.adapter = adapter
}
private fun initData() = lifecycleScope.launch(Dispatchers.IO) {
val list = requireContext().getMediaFile(selectionArgs = arrayOf(ConstObject.MIME_TYPE_PDF))
val pdfList = list.map {
DocumentBean(it.path, type)
val selectionArgs = arrayOf(ConstObject.MIME_TYPE_PDF)
if (type == TYPE_PDF) {
}
val bookmarkList = SpStringUtils.getSpStringList(BOOKMARK_KEY)
val list = requireContext().getMediaFile(selectionArgs = selectionArgs)
val documentList = list.map {
DocumentBean(it.path, type, bookmarkList.contains(it.path))
}
this@DocumentFragment.documentList = documentList
launch(Dispatchers.Main) {
adapter.submitList(pdfList)
adapter.submitList(documentList)
}
}
fun setRecentList() {
val recentList = documentList?.filter {
(System.currentTimeMillis() - File(it.path).lastModified()) < 300L * 24 * 60 * 60 * 1000
}
adapter.submitList(recentList)
}
fun setAllList() {
adapter.submitList(documentList)
}
fun setBookmarkList() {
val bookmarkList = documentList?.filter { it.isBookmarked }
adapter.submitList(bookmarkList)
}
......
package com.base.pdfviewerscannerwhite.ui.pdf
package com.base.pdfviewerscannerwhite.ui.document.pdf
import com.base.pdfviewerscannerwhite.bean.PdfPageBean
import com.base.pdfviewerscannerwhite.databinding.ActivityPdfBinding
import com.base.pdfviewerscannerwhite.helper.BaseActivity
import com.base.pdfviewerscannerwhite.utils.LogEx
import com.base.pdfviewerscannerwhite.utils.PermissionUtils.checkStorePermission
import com.base.pdfviewerscannerwhite.utils.PermissionUtils.requestStorePermission
import com.base.pdfviewerscannerwhite.utils.ToastUtils.toast
import com.github.barteksc.pdfviewer.scroll.DefaultScrollHandle
import com.tom_roush.pdfbox.pdmodel.PDDocument
import java.io.File
class PdfActivity : BaseActivity<ActivityPdfBinding>(), PdfView {
private val TAG = "PdfActivity"
private lateinit var pdfPresenter: PdfPresenter
override val binding: ActivityPdfBinding by lazy {
ActivityPdfBinding.inflate(layoutInflater)
}
var pafPath = ""
var pageNumber = 0
override fun initView() {
pdfPresenter = PdfPresenter(this, this)
if (checkStorePermission()){
pafPath = intent.extras?.getString("path", "") ?: ""
LogEx.logDebug(TAG, "pafPath=$pafPath")
if (checkStorePermission()) {
pdfPresenter.splitPdf("")
}else{
loadPdf()
} else {
requestStorePermission(launcher) {
pdfPresenter.splitPdf("")
loadPdf()
}
}
}
private fun loadPdf() {
try {
val file = File(pafPath)
if (!file.exists()) {
toast("pdf file not exists")
}
PDDocument.load(file)
loadPdfView(file)
} catch (e: Exception) {
}
}
private fun loadPdfView(file: File, password: String = "") {
binding.pdfview.fromFile(file)
.defaultPage(pageNumber)
.enableAnnotationRendering(true)
.scrollHandle(object : DefaultScrollHandle(this) {})
.spacing(10)
.onPageError { page, t ->
}.password(password).load()
}
override fun onAttachedToWindow() {
......
package com.base.pdfviewerscannerwhite.ui.pdf
package com.base.pdfviewerscannerwhite.ui.document.pdf
import android.content.Context
import android.os.Environment
......
package com.base.pdfviewerscannerwhite.ui.pdf
package com.base.pdfviewerscannerwhite.ui.document.pdf
import com.base.pdfviewerscannerwhite.bean.PdfPageBean
......
......@@ -11,7 +11,7 @@ import com.base.pdfviewerscannerwhite.BuildConfig
import com.base.pdfviewerscannerwhite.R
import com.base.pdfviewerscannerwhite.databinding.ActivityMainBinding
import com.base.pdfviewerscannerwhite.helper.BaseActivity
import com.base.pdfviewerscannerwhite.ui.pdf.PdfFragment
import com.base.pdfviewerscannerwhite.ui.document.DocumentFragment
import com.base.pdfviewerscannerwhite.utils.PermissionUtils.requestStorePermission
import com.base.pdfviewerscannerwhite.utils.ToastUtils.toast
......@@ -25,10 +25,11 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), MainView {
ActivityMainBinding.inflate(layoutInflater)
}
private val pdfFragment: PdfFragment by lazy {
PdfFragment()
private val pdfFragment: DocumentFragment by lazy {
DocumentFragment()
}
private var currentFragment = pdfFragment
private val fragments by lazy {
mutableListOf(pdfFragment)
}
......@@ -55,6 +56,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), MainView {
binding.viewPager2.registerOnPageChangeCallback(object :
ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
currentFragment = fragments[position]
}
})
......@@ -68,12 +70,17 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), MainView {
binding.llDocument.setOnClickListener {
changeTabSelect(it)
binding.ivPaixu.visibility = View.VISIBLE
currentFragment.setAllList()
}
binding.llRecent.setOnClickListener {
changeTabSelect(it)
binding.ivPaixu.visibility = View.GONE
currentFragment.setRecentList()
}
binding.llBookmark.setOnClickListener {
changeTabSelect(it)
currentFragment.setBookmarkList()
}
binding.llTool.setOnClickListener {
changeTabSelect(it)
......@@ -83,7 +90,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), MainView {
mainPresenter.starGmsScan(this)
}
binding.tvTittle.setOnClickListener {
requestStorePermission(launcher){}
requestStorePermission(launcher) {}
}
}
......
......@@ -57,7 +57,7 @@ class MainPresenter(
.addOnSuccessListener { intentSender: IntentSender ->
scannerLauncher.launch(IntentSenderRequest.Builder(intentSender).build())
}
.addOnFailureListener() { e: Exception ->
.addOnFailureListener { e: Exception ->
}
}
......
package com.base.pdfviewerscannerwhite.utils;
import android.content.Context;
import android.content.SharedPreferences;
import com.base.pdfviewerscannerwhite.helper.MyApplication;
import java.util.Set;
public class AppPreferences {
private static AppPreferences sInstance;
private SharedPreferences sharedPreferences;
private static final String PREF_FILE_NAME = "app_prefs"; // 偏好文件名
private AppPreferences(Context context) {
sharedPreferences = context.getSharedPreferences(PREF_FILE_NAME, Context.MODE_PRIVATE);
}
public static synchronized AppPreferences getInstance() {
if (sInstance == null) {
sInstance = new AppPreferences(MyApplication.context.getApplicationContext());
}
return sInstance;
}
// 通用 put 方法
public void put(String key, Object value) {
if (value instanceof Integer) {
sharedPreferences.edit().putInt(key, (Integer) value).apply();
} else if (value instanceof Long) {
sharedPreferences.edit().putLong(key, (Long) value).apply();
} else if (value instanceof Float) {
sharedPreferences.edit().putFloat(key, (Float) value).apply();
} else if (value instanceof Boolean) {
sharedPreferences.edit().putBoolean(key, (Boolean) value).apply();
} else if (value instanceof String) {
sharedPreferences.edit().putString(key, (String) value).apply();
} else if (value instanceof Double) {
sharedPreferences.edit().putString(key, (String) value.toString()).apply();
} else if (value instanceof Set) {
sharedPreferences.edit().putStringSet(key, (Set<String>) value).apply();
} else {
throw new IllegalArgumentException("Unsupported type: " + value.getClass());
}
}
public void put(String key, Object value, boolean isCommit) {
SharedPreferences.Editor editor = sharedPreferences.edit();
if (value instanceof Integer) {
editor.putInt(key, (Integer) value);
} else if (value instanceof Long) {
editor.putLong(key, (Long) value);
} else if (value instanceof Float) {
editor.putFloat(key, (Float) value);
} else if (value instanceof Boolean) {
editor.putBoolean(key, (Boolean) value);
} else if (value instanceof String) {
editor.putString(key, (String) value);
} else if (value instanceof Set) {
sharedPreferences.edit().putStringSet(key, (Set<String>) value).apply();
} else {
throw new IllegalArgumentException("Unsupported type: " + value.getClass());
}
// 根据 isCommit 参数的值决定使用 commit() 还是 apply()
if (isCommit) {
editor.commit();
} else {
editor.apply();
}
}
// 存入整数
public void putInt(String key, int value) {
sharedPreferences.edit().putInt(key, value).apply();
}
public void putStringSet(String key, Set value) {
sharedPreferences.edit().putStringSet(key, value).apply();
}
public Set<String> getStringSet(String key, Set<String> defaultValue) {
return sharedPreferences.getStringSet(key, defaultValue);
}
// 获取整数
public int getInt(String key, int defaultValue) {
return sharedPreferences.getInt(key, defaultValue);
}
// 存入长整数
public void putLong(String key, long value) {
sharedPreferences.edit().putLong(key, value).apply();
}
// 获取长整数
public long getLong(String key, long defaultValue) {
return sharedPreferences.getLong(key, defaultValue);
}
// 存入浮点数
public void putFloat(String key, float value) {
sharedPreferences.edit().putFloat(key, value).apply();
}
// 获取浮点数
public float getFloat(String key, float defaultValue) {
return sharedPreferences.getFloat(key, defaultValue);
}
// 存入布尔值
public void putBoolean(String key, boolean value) {
sharedPreferences.edit().putBoolean(key, value).apply();
}
// 获取布尔值
public boolean getBoolean(String key, boolean defaultValue) {
return sharedPreferences.getBoolean(key, defaultValue);
}
// 存入字符串
public void putString(String key, String value) {
sharedPreferences.edit().putString(key, value).apply();
}
// 获取字符串
public String getString(String key, String defaultValue) {
return sharedPreferences.getString(key, defaultValue);
}
// 检查某个键是否存在
public boolean contains(String key) {
return sharedPreferences.contains(key);
}
// 移除某个键
public void remove(String key) {
sharedPreferences.edit().remove(key).apply();
}
// 清除所有数据
public void clear() {
sharedPreferences.edit().clear().apply();
}
}
\ No newline at end of file
......@@ -6,7 +6,7 @@ import com.base.pdfviewerscannerwhite.BuildConfig
object LogEx {
val isOpen = true
val filterTAG = arrayOf(
"",
"MediaStoreUtils",
)
fun logDebug(tag: String, content: String, isMust: Boolean = false) {
......
package com.base.pdfviewerscannerwhite.utils
object SpStringUtils {
const val BOOKMARK_KEY = "bookmark_key"
fun getSpStringList(key: String): List<String> {
val sp = AppPreferences.getInstance().getString(key, "")
return if (sp.equals("")) {
listOf()
} else {
sp.split("|||")
}
}
fun addSpString(key: String, value: String) {
val list = getSpStringList(key).toMutableList()
list.add(value)
val string = list.joinToString(separator = "|||")
AppPreferences.getInstance().put(key, string)
}
fun deleteSpString(key: String, value: String) {
val list = getSpStringList(key).toMutableList()
list.remove(value)
val string = list.joinToString(separator = "|||")
AppPreferences.getInstance().put(key, string)
}
}
\ No newline at end of file
......@@ -5,7 +5,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".ui.pdf.PdfActivity">
tools:context=".ui.document.pdf.PdfActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
......@@ -21,6 +21,12 @@
</com.google.android.material.appbar.AppBarLayout>
<com.github.barteksc.pdfviewer.PDFView
android:id="@+id/pdfview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#E0E0E0"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file
......@@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.pdf.PdfFragment">
tools:context=".ui.document.DocumentFragment">
<androidx.recyclerview.widget.RecyclerView
......
......@@ -17,7 +17,8 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:src="@mipmap/h_pdfiocn" />
tools:src="@mipmap/h_pdfiocn"
tools:ignore="ContentDescription" />
<FrameLayout
......
......@@ -2,4 +2,5 @@
plugins {
alias(libs.plugins.androidApplication) apply false
alias(libs.plugins.jetbrainsKotlinAndroid) apply false
alias(libs.plugins.androidLibrary) apply false
}
\ No newline at end of file
......@@ -5,12 +5,10 @@ coreKtx = "1.8.0"
junit = "4.13.2"
junitVersion = "1.1.5"
espressoCore = "3.5.1"
appcompat = "1.6.1"
appcompat = "1.7.0"
material = "1.10.0"
activity = "1.8.0"
constraintlayout = "2.1.4"
navigationFragmentKtx = "2.6.0"
navigationUiKtx = "2.6.0"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
......@@ -21,10 +19,9 @@ androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
androidx-navigation-fragment-ktx = { group = "androidx.navigation", name = "navigation-fragment-ktx", version.ref = "navigationFragmentKtx" }
androidx-navigation-ui-ktx = { group = "androidx.navigation", name = "navigation-ui-ktx", version.ref = "navigationUiKtx" }
[plugins]
androidApplication = { id = "com.android.application", version.ref = "agp" }
jetbrainsKotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
androidLibrary = { id = "com.android.library", version.ref = "agp" }
......@@ -54,3 +54,5 @@ dependencyResolutionManagement {
rootProject.name = "PDF Viewer Scanner White"
include(":app")
include(":android-pdf-viewer")
include(":PdfiumAndroid")
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment