Commit c4e192c2 authored by wanglei's avatar wanglei

...提交部分功能...

parent 6f1f0d10
......@@ -9,7 +9,7 @@ android {
defaultConfig {
applicationId "com.base.superpdfreader"
minSdk 24
minSdk 26
targetSdk 34
versionCode 1
versionName "1.0"
......@@ -49,8 +49,6 @@ dependencies {
androidTestImplementation libs.androidx.espresso.core
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
//工具库
implementation("com.blankj:utilcodex:1.31.1")
//ui第三方
implementation("com.github.JavaNoober.BackgroundLibrary:libraryx:1.7.6")
......@@ -62,7 +60,12 @@ dependencies {
//pdf文件操作
implementation 'com.github.barteksc:pdfium-android:1.7.1'
//word内容提取
implementation 'org.apache.poi:poi:4.1.2'
implementation 'org.apache.poi:poi-ooxml:4.1.2'
//apache / poi 内容提取
//有个问题是gradle版本需要升级到8.4
//https://github.com/apache/poi
implementation 'org.apache.poi:poi-ooxml:5.2.5'
implementation 'org.apache.poi:poi-scratchpad:5.2.5'
implementation 'com.fasterxml:aalto-xml:1.3.0'//XML格式数据的解析和生成,通过Jackson XML模块。
implementation 'stax:stax-api:1.0.1'//处理XML文档的Java API
}
\ No newline at end of file
......@@ -18,6 +18,9 @@
android:supportsRtl="true"
android:theme="@style/Theme.SuperPDFReader"
tools:targetApi="31">
<activity
android:name=".activity.XlsBrowserActivity"
android:exported="false" />
<activity
android:name=".activity.DocBrowserActivity"
android:exported="false" />
......
......@@ -16,8 +16,8 @@ import com.base.superpdfreader.fragment.DocumentListFragment.Companion.MODE_PPT
import com.base.superpdfreader.fragment.DocumentListFragment.Companion.MODE_WORD
import com.base.superpdfreader.helps.BaseActivity
import com.base.superpdfreader.helps.MediaStoreHelp.updateMediaStore
import com.base.superpdfreader.utils.BarUtils
import com.base.superpdfreader.view.PDFOperationDialog.showPDFCreateConverter
import com.blankj.utilcode.util.BarUtils
import com.google.android.material.tabs.TabLayoutMediator
class MainActivity : BaseActivity<ActivityMainBinding>() {
......
package com.base.superpdfreader.activity
import android.annotation.SuppressLint
import android.util.Log
import androidx.lifecycle.lifecycleScope
import com.base.superpdfreader.databinding.ActivityDocBrowserBinding
import com.base.superpdfreader.helps.BaseActivity
import com.base.superpdfreader.helps.LogEx
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.apache.poi.hssf.usermodel.HSSFWorkbook
import org.apache.poi.hwpf.HWPFDocument
import org.apache.poi.xwpf.extractor.XWPFWordExtractor
import org.apache.poi.xwpf.usermodel.XWPFDocument
import java.io.File
import java.io.FileInputStream
import java.nio.charset.Charset
class DocBrowserActivity : BaseActivity<ActivityDocBrowserBinding>() {
private var TAG = "DocBrowserActivity"
override val binding: ActivityDocBrowserBinding by lazy {
ActivityDocBrowserBinding.inflate(layoutInflater)
}
@SuppressLint("SetJavaScriptEnabled")
override fun initView() {
val path = intent.extras?.getString("Path") ?: ""
val uri = intent.extras?.getString("Uri") ?: ""
LogEx.logDebug(TAG, "path=$path uri=$uri")
initWebView()
if (path.contains(".docx")) {
showDocxByPoi(path)
} else {
showDocByPoi(path)
}
}
// https://blog.51cto.com/u_16175512/6728878
private fun initWebView() {
binding.webView.settings.setLoadWithOverviewMode(true)
binding.webView.settings.setSupportZoom(true)
binding.webView.settings.setBuiltInZoomControls(true)
}
// https://blog.51cto.com/u_16175512/6728878
//docx
fun showDocxByPoi(path: String) = lifecycleScope.launch(Dispatchers.IO) {
val file = File(path)
// val doc = XWPFDocument(FileInputStream(file))
val doc = XWPFDocument(FileInputStream(file))
val extractor = XWPFWordExtractor(doc)
val htmlContent = extractor.getText()
launch(Dispatchers.Main) {
binding.webView.loadDataWithBaseURL(null, htmlContent, "text/html", "UTF-8", null)
}
}
fun showDocByPoi(path: String) = lifecycleScope.launch(Dispatchers.IO) {
val htmlContent = convertDocToHtml(path)
launch(Dispatchers.Main) {
binding.webView.loadDataWithBaseURL(null, htmlContent, "text/html", "UTF-8", null)
}
}
fun convertDocToHtml(docFilePath: String): String {
val htmlBuilder = StringBuilder()
htmlBuilder.append("<html><head><title>Document</title></head><body>")
try {
val fileInputStream = FileInputStream(File(docFilePath))
val doc = HWPFDocument(fileInputStream)
val range = doc.range
// 遍历文档中的所有段落
for (i in 0 until range.numParagraphs()) {
val paragraph = range.getParagraph(i)
val text = paragraph.text()
htmlBuilder.append("<p>$text</p>")
}
htmlBuilder.append("</body></html>")
} catch (e: Exception) {
e.printStackTrace()
}
return htmlBuilder.toString()
}
}
\ No newline at end of file
package com.base.superpdfreader.activity
import androidx.lifecycle.lifecycleScope
import com.base.superpdfreader.R
import com.base.superpdfreader.databinding.ActivityXlsBrowserBinding
import com.base.superpdfreader.helps.BaseActivity
import com.base.superpdfreader.helps.LogEx
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
class XlsBrowserActivity : BaseActivity<ActivityXlsBrowserBinding>() {
val TAG = "XlsBrowserActivity"
override val binding: ActivityXlsBrowserBinding by lazy {
ActivityXlsBrowserBinding.inflate(layoutInflater)
}
override fun initView() {
val path = intent.extras?.getString("Path") ?: ""
val uri = intent.extras?.getString("Uri") ?: ""
LogEx.logDebug(TAG, "path=$path uri=$uri")
}
}
\ No newline at end of file
package com.base.superpdfreader.adapter
import android.annotation.SuppressLint
import android.net.Uri
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
......@@ -39,15 +40,19 @@ class DocumentAdapter(val itemClick: (bean: DocumentBean) -> Unit) :
}
@SuppressLint("NotifyDataSetChanged")
fun addData(type: String, drawable: Int, list: List<File>) {
fun addData(type: String, drawable: Int, list: List<Pair<File, Uri>>) {
val beans = list.map { file ->
val beans = list.map { pair ->
val file = pair.first
val uri = pair.second
val bean = DocumentBean(
drawable,
file.name,
file.lastModified(),
file.length(),
file.absolutePath, type
file.absolutePath,
uri,
type
)
bean
}
......
......@@ -2,6 +2,7 @@ package com.base.superpdfreader.bean
import android.annotation.SuppressLint
import android.graphics.drawable.Drawable
import android.net.Uri
import com.base.superpdfreader.helps.KotlinExt.toFormatSize
import java.text.SimpleDateFormat
......@@ -11,6 +12,7 @@ data class DocumentBean(
val time: Long = 0,
val size: Long = 0,
val path: String = "",
val uri: Uri = Uri.EMPTY,
val type: String = "",
) {
@SuppressLint("SimpleDateFormat")
......
package com.base.superpdfreader.fragment
import android.net.Uri
import android.provider.MediaStore
import android.widget.Toast
import androidx.core.content.ContextCompat
......@@ -60,7 +61,7 @@ class DocumentListFragment() : BaseFragment<FragmentDocumentListBinding>() {
}
binding.rv.adapter = adapter
if (checkStorePermission()) {
if (requireContext().checkStorePermission()) {
initData()
}
}
......@@ -94,7 +95,7 @@ class DocumentListFragment() : BaseFragment<FragmentDocumentListBinding>() {
// adapter.addData(MODE_PDF, R.mipmap.pdf, files)
// }
// }
val files = arrayListOf<File>()
val files = arrayListOf<Pair<File, Uri>>()
requireContext().geFileMedia(files, arrayOf("application/pdf"))
launch(Dispatchers.Main) {
adapter.addData(MODE_PDF, R.mipmap.pdf, files)
......@@ -103,7 +104,7 @@ class DocumentListFragment() : BaseFragment<FragmentDocumentListBinding>() {
}
MODE_WORD -> {
val files = arrayListOf<File>()
val files = arrayListOf<Pair<File, Uri>>()
requireContext().geFileMedia(
files,
arrayOf(
......@@ -117,7 +118,7 @@ class DocumentListFragment() : BaseFragment<FragmentDocumentListBinding>() {
}
MODE_PPT -> {
val files = arrayListOf<File>()
val files = arrayListOf<Pair<File, Uri>>()
requireContext().geFileMedia(
files, arrayOf(
"application/vnd.ms-powerpoint",
......@@ -131,7 +132,7 @@ class DocumentListFragment() : BaseFragment<FragmentDocumentListBinding>() {
MODE_EXCEL -> {
val files = arrayListOf<File>()
val files = arrayListOf<Pair<File, Uri>>()
requireContext().geFileMedia(
files, arrayOf(
"application/vnd.ms-excel",
......@@ -139,7 +140,7 @@ class DocumentListFragment() : BaseFragment<FragmentDocumentListBinding>() {
)
)
launch(Dispatchers.Main) {
adapter.addData(MODE_PPT, R.mipmap.ppt, files)
adapter.addData(MODE_EXCEL, R.mipmap.xls, files)
}
}
}
......@@ -147,7 +148,7 @@ class DocumentListFragment() : BaseFragment<FragmentDocumentListBinding>() {
override fun onResume() {
super.onResume()
binding.llPermission.isVisible = !checkStorePermission()
binding.llPermission.isVisible = !requireContext().checkStorePermission()
}
companion object {
......
package com.base.superpdfreader.helps
import android.app.Dialog
import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.viewbinding.ViewBinding
import com.base.superpdfreader.MainActivity
import com.blankj.utilcode.util.ActivityUtils
import com.blankj.utilcode.util.BarUtils
import com.base.superpdfreader.utils.ActivityManagerUtils
import com.base.superpdfreader.utils.BarUtils
abstract class BaseActivity<T : ViewBinding> : AppCompatActivity() {
......@@ -37,11 +38,19 @@ abstract class BaseActivity<T : ViewBinding> : AppCompatActivity() {
protected fun finishToMain() {
if (this !is MainActivity && !ActivityUtils.isActivityExistsInStack(MainActivity::class.java)) {
if (this !is MainActivity && !ActivityManagerUtils.getInstance().isActivityInStack(MainActivity::class.java)) {
startActivity(Intent(this, MainActivity::class.java))
}
finish()
}
var dialog: Dialog? = null
override fun onDestroy() {
super.onDestroy()
ActivityManagerUtils.getInstance().removeActivity(this)
if (dialog != null) {
dialog?.dismiss()
}
}
}
\ No newline at end of file
package com.base.superpdfreader.helps
import android.annotation.SuppressLint
import android.content.ContentUris
import android.content.Context
import android.database.Cursor
import android.graphics.drawable.AdaptiveIconDrawable
import android.media.MediaScannerConnection
import android.net.Uri
import android.os.Environment
import android.provider.MediaStore
import com.base.superpdfreader.bean.DocumentBean
import java.io.File
object MediaStoreHelp {
@SuppressLint("Range")
fun Context.geFileMedia(
list: ArrayList<File>,
list: ArrayList<Pair<File, Uri>>,
selectionArgs: Array<String>
): ArrayList<File> {
): ArrayList<Pair<File, Uri>> {
val projection = arrayOf(
// MediaStore.Files.FileColumns._ID,
MediaStore.Files.FileColumns._ID,
MediaStore.Files.FileColumns.DATA,
// MediaStore.Files.FileColumns.MIME_TYPE,
// MediaStore.Files.FileColumns.TITLE,
......@@ -33,9 +33,10 @@ object MediaStoreHelp {
// val selectionArgs = arrayOf("application/zip")
var cursor: Cursor? = null
val externalUri = MediaStore.Files.getContentUri("external") // 你也可以使用INTERNAL_CONTENT_URI来查询内部存储
try {
cursor = contentResolver.query(
MediaStore.Files.getContentUri("external"), // 你也可以使用INTERNAL_CONTENT_URI来查询内部存储
externalUri,
projection,
selection,
selectionArgs,
......@@ -51,8 +52,15 @@ object MediaStoreHelp {
// val size =
// cursor.getString(cursor.getColumnIndex(MediaStore.Files.FileColumns.SIZE))
// .toLong()
val uri =
ContentUris.withAppendedId(
externalUri,
cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns._ID))
)
// 其他属性...
list.add(File(path))
list.add(
Pair(File(path), uri)
)
}
}
} catch (e: Exception) {
......
package com.base.superpdfreader.helps
import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.Settings
import com.blankj.utilcode.constant.PermissionConstants
import com.blankj.utilcode.util.PermissionUtils
import androidx.core.app.ActivityCompat
object PermissionHelp {
fun checkStorePermission(): Boolean {
fun Context.checkStorePermission(): Boolean {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
Environment.isExternalStorageManager()
} else {
PermissionUtils.isGranted(PermissionConstants.STORAGE)
val readPermission = ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
val writePermission = ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
return readPermission == PackageManager.PERMISSION_GRANTED && writePermission == PackageManager.PERMISSION_GRANTED;
}
}
......@@ -35,8 +38,8 @@ object PermissionHelp {
result.invoke(checkStorePermission())
}
} else {
PermissionUtils.permissionGroup(PermissionConstants.STORAGE).callback { isAllGranted, _, _, _ ->
result.invoke(isAllGranted)
launcher.launch(arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)) { map ->
result(map.values.all { it })
}
}
......
package com.base.superpdfreader.utils;
import android.app.Activity;
import java.util.Stack;
public class ActivityManagerUtils {
private static ActivityManagerUtils instance;
private Stack<Activity> activityStack = new Stack<>();
private ActivityManagerUtils() {
}
public static ActivityManagerUtils getInstance() {
if (instance == null) {
instance = new ActivityManagerUtils();
}
return instance;
}
/**
* 添加Activity到堆栈
*/
public void addActivity(Activity activity) {
activityStack.add(activity);
}
/**
* 移除Activity从堆栈
*/
public void removeActivity(Activity activity) {
activityStack.remove(activity);
}
/**
* 获取当前Activity(堆栈中最后一个压入的)
*/
public Activity getCurrentActivity() {
return activityStack.lastElement();
}
/**
* 结束指定的Activity
*/
public void finishActivity(Activity activity) {
if (activity != null) {
activityStack.remove(activity);
activity.finish();
}
}
/**
* 结束所有Activity
*/
public void finishAllActivity() {
for (Activity activity : activityStack) {
if (activity != null) {
activity.finish();
}
}
activityStack.clear();
}
/**
* 检查Activity是否存在于堆栈中
*/
public boolean isActivityInStack(Class<?> cls) {
boolean isExist = false;
if (cls != null) {
for (Activity activity : activityStack) {
if (cls.equals(activity.getClass())) {
isExist = true;
break;
}
}
}
return isExist;
}
public Activity getTopActivity() {
if (activityStack.empty()) {
return null;
} else {
return activityStack.peek();
}
}
}
\ No newline at end of file
package com.base.superpdfreader.utils
//noinspection SuspiciousImport
import android.app.Activity
import android.content.Context
import android.content.res.Resources
import android.graphics.Color
import android.os.Build
import android.view.View
import android.view.ViewGroup
import android.view.Window
import android.view.WindowManager
import androidx.annotation.ColorInt
object BarUtils {
fun setStatusBarLightMode(activity: Activity, isLightMode: Boolean) {
setStatusBarLightMode(activity.window, isLightMode)
}
private fun setStatusBarLightMode(window: Window, isLightMode: Boolean) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val decorView = window.decorView
var vis = decorView.systemUiVisibility
vis = if (isLightMode) {
vis or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
} else {
vis and View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.inv()
}
decorView.systemUiVisibility = vis
}
}
fun setStatusBarColor(activity: Activity, @ColorInt color: Int): View? {
return setStatusBarColor(activity, color, false)
}
private fun setStatusBarColor(activity: Activity, @ColorInt color: Int, isDecor: Boolean): View? {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return null
transparentStatusBar(activity)
return applyStatusBarColor(activity, color, isDecor)
}
private fun applyStatusBarColor(activity: Activity, color: Int, isDecor: Boolean): View {
return applyStatusBarColor(activity.window, color, isDecor)
}
private fun transparentStatusBar(activity: Activity) {
transparentStatusBar(activity.window)
}
private fun transparentStatusBar(window: Window) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
val option = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
val vis = window.decorView.systemUiVisibility
window.decorView.systemUiVisibility = option or vis
window.statusBarColor = Color.TRANSPARENT
} else {
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
}
}
private fun applyStatusBarColor(window: Window, color: Int, isDecor: Boolean): View {
val parent =
if (isDecor) window.decorView as ViewGroup else (window.findViewById<View>(android.R.id.content) as ViewGroup)!!
var fakeStatusBarView =
parent.findViewWithTag<View>(TAG_STATUS_BAR)
if (fakeStatusBarView != null) {
if (fakeStatusBarView.visibility == View.GONE) {
fakeStatusBarView.visibility = View.VISIBLE
}
fakeStatusBarView.setBackgroundColor(color)
} else {
fakeStatusBarView = createStatusBarView(window.context, color)
parent.addView(fakeStatusBarView)
}
return fakeStatusBarView
}
private fun createStatusBarView(context: Context, color: Int): View {
val statusBarView = View(context)
statusBarView.layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight()
)
statusBarView.setBackgroundColor(color)
statusBarView.tag = TAG_STATUS_BAR
return statusBarView
}
///////////////////////////////////////////////////////////////////////////
// status bar
///////////////////////////////////////////////////////////////////////////
private const val TAG_STATUS_BAR = "TAG_STATUS_BAR"
fun getStatusBarHeight(): Int {
val resources = Resources.getSystem()
val resourceId = resources.getIdentifier("status_bar_height", "dimen", "android")
return resources.getDimensionPixelSize(resourceId)
}
}
\ No newline at end of file
......@@ -7,6 +7,7 @@ import android.view.LayoutInflater
import com.base.superpdfreader.R
import com.base.superpdfreader.activity.DocBrowserActivity
import com.base.superpdfreader.activity.PdfBrowserActivity
import com.base.superpdfreader.activity.XlsBrowserActivity
import com.base.superpdfreader.bean.DocumentBean
import com.base.superpdfreader.databinding.DialogDocumentDetailBinding
import com.base.superpdfreader.fragment.DocumentListFragment
......@@ -71,20 +72,29 @@ object DocumentDetailDialog {
}
binding.llOpen.setOnClickListener {
when (UI_MODE) {
MODE_PDF -> {
startActivity(Intent(this, PdfBrowserActivity::class.java).apply {
putExtra("Path", bean.path)
putExtra("Uri", bean.uri.toString())
})
}
MODE_WORD -> {
startActivity(Intent(this, DocBrowserActivity::class.java).apply {
putExtra("Path", bean.path)
putExtra("Uri", bean.uri.toString())
})
}
MODE_EXCEL -> {
startActivity(Intent(this, XlsBrowserActivity::class.java).apply {
putExtra("Path", bean.path)
putExtra("Uri", bean.uri.toString())
})
}
}
dialog.dismiss()
}
}
}
\ No newline at end of file
......@@ -7,4 +7,8 @@
android:layout_height="match_parent"
tools:context=".activity.DocBrowserActivity">
<WebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activity.XlsBrowserActivity">
<WebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
[versions]
agp = "8.0.0"
agp = "8.3.1"
kotlin = "1.9.0"
coreKtx = "1.10.1"
junit = "4.13.2"
......
#Thu Jun 06 09:57:27 CST 2024
#Thu Jun 20 10:47:04 CST 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
......@@ -22,6 +22,12 @@ dependencyResolutionManagement {
maven { url "https://dl-maven-android.mintegral.com/repository/mbridge_android_sdk_oversea" }
maven { url "https://artifact.bytedance.com/repository/pangle" }
maven { url "https://s01.oss.sonatype.org/content/groups/public" }
maven { url "https://maven.google.com" }
maven{ url 'https://maven.aliyun.com/nexus/content/groups/public/'}
maven { url 'https://maven.aliyun.com/repository/public' }
maven { url 'https://maven.aliyun.com/repository/central' }
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
}
}
......
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