Commit fa5cb099 authored by wanglei's avatar wanglei

初始化

parent d9ea9d36
...@@ -8,7 +8,7 @@ android { ...@@ -8,7 +8,7 @@ android {
compileSdk = 34 compileSdk = 34
defaultConfig { defaultConfig {
applicationId = "com.base.pdfoneread" applicationId = "com.base.pdfreaderallpdfreader"
minSdk = 24 minSdk = 24
targetSdk = 34 targetSdk = 34
versionCode = 1 versionCode = 1
...@@ -61,4 +61,52 @@ dependencies { ...@@ -61,4 +61,52 @@ dependencies {
implementation("com.airbnb.android:lottie:6.4.0") implementation("com.airbnb.android:lottie:6.4.0")
implementation("com.github.pokercc:ExpandableRecyclerView:0.9.3") implementation("com.github.pokercc:ExpandableRecyclerView:0.9.3")
//mlkit
implementation("com.google.android.gms:play-services-mlkit-document-scanner:16.0.0-beta1")
//Pdf库
implementation("com.tom-roush:pdfbox-android:2.0.27.0")
api(project(":pdflibrary"))
//
//Word库
//PPT库
//Excel库
api(project(":library"))
//广告
implementation("com.google.android.gms:play-services-ads:23.1.0")
implementation("com.google.ads.mediation:applovin:12.4.3.0")
implementation("com.google.ads.mediation:facebook:6.17.0.0")
implementation("com.google.ads.mediation:mintegral:16.7.21.0")
implementation("com.google.ads.mediation:pangle:5.9.0.4.0")
//ump
implementation("com.google.android.ump:user-messaging-platform:3.0.0")
//firebase
implementation(platform("com.google.firebase:firebase-bom:32.3.1"))
implementation("com.google.firebase:firebase-messaging")
implementation("com.google.firebase:firebase-analytics-ktx")
implementation("com.google.firebase:firebase-crashlytics")
implementation("com.google.firebase:firebase-messaging-directboot")
//facebook
implementation("com.facebook.android:facebook-android-sdk:[8,9)")
//网络请求和解析
implementation("com.google.code.gson:gson:2.11.0")
// define a BOM and its version
implementation(platform("com.squareup.okhttp3:okhttp-bom:4.12.0"))
// define any required OkHttp artifacts without version
implementation("com.squareup.okhttp3:okhttp")
implementation("com.squareup.okhttp3:logging-interceptor")
//mintegral
implementation("com.reyun.solar.engine.oversea:solar-engine-core:1.2.8.3")
//work
implementation("androidx.work:work-runtime-ktx:2.7.1") // 请使用最新版本
} }
\ No newline at end of file
{
"project_info": {
"project_number": "618927174476",
"project_id": "scream-11bf5",
"storage_bucket": "scream-11bf5.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:618927174476:android:08858366fed11d3b2455e9",
"android_client_info": {
"package_name": "com.base.pdfreaderallpdfreader"
}
},
"oauth_client": [],
"api_key": [
{
"current_key": "AIzaSyDlEmOxb1M343Tv-FixB0ieQ3NQO0I3ibQ"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": []
}
}
}
],
"configuration_version": "1"
}
\ No newline at end of file
...@@ -18,4 +18,13 @@ ...@@ -18,4 +18,13 @@
# If you keep the line number information, uncomment this to # If you keep the line number information, uncomment this to
# hide the original source file name. # hide the original source file name.
#-renamesourcefileattribute SourceFile #-renamesourcefileattribute SourceFile
\ No newline at end of file
-keep class com.base.pdfoneread.bean.** { *; }
-keep class com.google.gson.reflect.** { *; }
-keep class com.google.gson.stream.** { *; }
-keepattributes *Annotation*
-keep class * extends com.google.gson.TypeAdapter
-keep class * extends com.google.gson.JsonSerializer
-keep class * extends com.google.gson.Deserializer
-keep class com.google.gson.TypeAdapters{*;}
\ No newline at end of file
...@@ -45,6 +45,13 @@ ...@@ -45,6 +45,13 @@
android:launchMode="singleTop" android:launchMode="singleTop"
android:screenOrientation="portrait" android:screenOrientation="portrait"
tools:ignore="DiscouragedApi,LockedOrientationActivity" /> tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-3940256099942544~3347511713" />
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="@string/facebook_app_id" />
</application> </application>
</manifest> </manifest>
\ No newline at end of file
package com.base.pdfoneread.ads
import android.animation.ObjectAnimator
import android.animation.ValueAnimator.INFINITE
import android.app.AlertDialog
import android.content.Context
import android.view.LayoutInflater
import android.view.animation.LinearInterpolator
import com.base.pdfoneread.R
import com.base.pdfoneread.databinding.DialogAdPreparingBinding
object AdDialog {
fun Context.showAdPreparingDialog(): AlertDialog {
val binding = DialogAdPreparingBinding.inflate(LayoutInflater.from(this))
val dialog = AlertDialog.Builder(this).create()
dialog.setView(binding.root)
dialog.setCancelable(false)
dialog.setCanceledOnTouchOutside(true)
dialog.show()
val params = dialog.window?.attributes
params?.width = resources.getDimensionPixelOffset(R.dimen.dp_200)
params?.height = resources.getDimensionPixelOffset(R.dimen.dp_146)
dialog.window?.attributes = params
dialog.window?.setBackgroundDrawableResource(android.R.color.transparent)
// 创建一个旋转动画
val rotateAnimator = ObjectAnimator.ofFloat(binding.iv, "rotation", 0f, -360f)
rotateAnimator.setDuration(1000) // 设置动画持续时间为1000毫秒
rotateAnimator.repeatCount = INFINITE
rotateAnimator.interpolator = LinearInterpolator() // 设置插值器为线性插值
rotateAnimator.start()
return dialog
}
}
\ No newline at end of file
package com.base.pdfoneread.ads
import com.base.pdfoneread.ads.AdmobHelper.open_limit_click
import com.base.pdfoneread.ads.AdmobHelper.open_limit_request
import com.base.pdfoneread.ads.AdmobHelper.open_limit_show
import com.base.pdfoneread.ads.AdmobHelper.inter_limit_request
import com.base.pdfoneread.ads.AdmobHelper.inter_limit_show
import com.base.pdfoneread.ads.AdmobHelper.inter_limit_click
import com.base.pdfoneread.ads.AdmobHelper.native_limit_request
import com.base.pdfoneread.ads.AdmobHelper.native_limit_show
import com.base.pdfoneread.ads.AdmobHelper.native_limit_click
import com.base.pdfoneread.helper.EventUtils
import com.base.pdfoneread.utils.AppPreferences
import com.base.pdfoneread.utils.LogEx
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale
object AdDisplayUtils {
//region open
private val open_max_request = AppPreferences.getInstance().getString(open_limit_request, "15").toInt()
private val open_max_show = AppPreferences.getInstance().getString(open_limit_show, "10").toInt()
private val open_max_click = AppPreferences.getInstance().getString(open_limit_click, "1").toInt()
fun incrementOpenRequestCount() {
currentOpenRequest += 1
}
fun incrementOpenShow() {
currentOpenShow += 1
}
fun incrementClickShow() {
currentOpenClick += 1
}
//当前开屏请求次数
private var currentOpenRequest = 0
get() {
return AppPreferences.getInstance().getInt("currentOpenRequest_${currentDate()}", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("currentOpenRequest_${currentDate()}", value, true)
}
//当前开屏展示次数
private var currentOpenShow = 0
get() {
return AppPreferences.getInstance().getInt("currentOpenShow_${currentDate()}", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("currentOpenShow_${currentDate()}", value, true)
}
//当前开屏点击次数
private var currentOpenClick = 0
get() {
return AppPreferences.getInstance().getInt("currentOpenClick_${currentDate()}", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("currentOpenClick_${currentDate()}", value, true)
}
fun shouldShowOpenAd(): Boolean {
if (currentOpenRequest > open_max_request) {
LogEx.logDebug(TAG, "currentOpenRequest=$currentOpenRequest open_max_request=$open_max_request")
EventUtils.event("ad_limit", "currentOpenRequest=$currentOpenRequest open_max_request=$open_max_request")
return false
}
if (currentOpenShow > open_max_show) {
LogEx.logDebug(TAG, "currentOpenShow=$currentOpenShow open_max_show=$open_max_show")
EventUtils.event("ad_limit", "currentOpenShow=$currentOpenShow open_max_show=$open_max_show")
return false
}
if (currentOpenClick > open_max_click) {
LogEx.logDebug(TAG, "currentOpenClick=$currentOpenClick open_max_click=$open_max_click")
EventUtils.event("ad_limit", "currentOpenClick=$currentOpenClick open_max_click=$open_max_click")
return false
}
return true
}
//endregion
//region inter
private val inter_max_request = AppPreferences.getInstance().getString(inter_limit_request, "15").toInt()
private val inter_max_show = AppPreferences.getInstance().getString(inter_limit_show, "10").toInt()
private val inter_max_click = AppPreferences.getInstance().getString(inter_limit_click, "1").toInt()
fun incrementInterRequestCount() {
currentInterRequest += 1
}
fun incrementInterShowCount() {
currentInterShow += 1
}
fun incrementInterClickCount() {
currentInterClick += 1
}
//当前插页请求次数
private var currentInterRequest = 0
get() {
return AppPreferences.getInstance().getInt("currentInterRequest_${currentDate()}", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("currentInterRequest_${currentDate()}", value, true)
}
//当前插页展示次数
private var currentInterShow = 0
get() {
return AppPreferences.getInstance().getInt("currentInterShow_${currentDate()}", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("currentInterShow_${currentDate()}", value, true)
}
//当前插页点击次数
private var currentInterClick = 0
get() {
return AppPreferences.getInstance().getInt("currentInterClick_${currentDate()}", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("currentInterClick_${currentDate()}", value, true)
}
fun shouldShowInterAd(): Boolean {
if (currentInterRequest > inter_max_request) {
LogEx.logDebug(TAG, "currentInterRequest=$currentInterRequest inter_max_request=$inter_max_request")
EventUtils.event("ad_limit", "currentInterRequest=$currentInterRequest inter_max_request=$inter_max_request")
return false
}
if (currentInterShow > inter_max_show) {
LogEx.logDebug(TAG, "currentInterShow=$currentInterShow inter_max_show=$inter_max_show")
EventUtils.event("ad_limit", "currentInterShow=$currentInterShow inter_max_show=$inter_max_show")
return false
}
if (currentInterClick > inter_max_click) {
LogEx.logDebug(TAG, "currentInterClick=$currentInterClick inter_max_click=$inter_max_click")
EventUtils.event("ad_limit", "currentInterClick=$currentInterClick inter_max_click=$inter_max_click")
return false
}
return true
}
//endregion
//region native
private val native_max_request = AppPreferences.getInstance().getString(native_limit_request, "15").toInt()
private val native_max_show = AppPreferences.getInstance().getString(native_limit_show, "10").toInt()
private val native_max_click = AppPreferences.getInstance().getString(native_limit_click, "1").toInt()
fun incrementNativeRequestCount() {
currentNativeRequest += 1
}
fun incrementNativeShowCount() {
currentNativeShow += 1
}
fun incrementNativeClickCount() {
currentNativeClick += 1
}
private var currentNativeRequest = 0
get() {
return AppPreferences.getInstance().getInt("currentNativeRequest_${currentDate()}", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("currentNativeRequest_${currentDate()}", value, true)
}
private var currentNativeShow = 0
get() {
return AppPreferences.getInstance().getInt("currentNativeShow_${currentDate()}", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("currentNativeShow_${currentDate()}", value, true)
}
private var currentNativeClick = 0
get() {
return AppPreferences.getInstance().getInt("currentNativeClick_${currentDate()}", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("currentNativeClick_${currentDate()}", value, true)
}
fun shouldShowNative(): Boolean {
if (currentNativeRequest > native_max_request) {
LogEx.logDebug(TAG, "currentNativeRequest=$currentNativeRequest native_max_request=$native_max_request")
EventUtils.event("ad_limit", "currentNativeRequest=$currentNativeRequest native_max_request=$native_max_request")
return false
}
if (currentNativeShow > native_max_show) {
LogEx.logDebug(TAG, "currentNativeShow=$currentNativeShow native_max_show=$native_max_show")
EventUtils.event("ad_limit", "currentNativeShow=$currentNativeShow native_max_show=$native_max_show")
return false
}
if (currentNativeClick > native_max_click) {
LogEx.logDebug(TAG, "currentNativeClick=$currentNativeClick native_max_click=$native_max_click")
EventUtils.event("ad_limit", "currentNativeClick=$currentNativeClick native_max_click=$native_max_click")
return false
}
return true
}
//endregion
private val TAG = "AdDisplayUtils"
private fun currentDate(): String {
val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
val currentDate = Calendar.getInstance().time
return dateFormat.format(currentDate)
}
}
package com.base.pdfoneread.ads
import android.app.Activity
import com.base.pdfoneread.ads.admob.AdmobInterstitialUtils
import com.base.pdfoneread.ads.admob.AdmobNativeUtils
import com.base.pdfoneread.helper.EventUtils
import com.base.pdfoneread.ui.MyApplication
import com.base.pdfoneread.utils.AppPreferences
import com.google.android.gms.ads.MobileAds
import java.util.concurrent.atomic.AtomicBoolean
object AdmobHelper {
//开屏限制
const val open_limit_request = "open_limit_request"
const val open_limit_show = "open_limit_show"
const val open_limit_click = "open_limit_click"
//插页限制
const val inter_limit_request = "inter_limit_request"
const val inter_limit_show = "inter_limit_show"
const val inter_limit_click = "inter_limit_click"
//原生广告限制
const val native_limit_request = "native_limit_request"
const val native_limit_show = "native_limit_show"
const val native_limit_click = "native_limit_click"
//是否展示多语言
val showLanPage = "showLanPage"
//开屏加载ad时间
val open_ad_loading = "open_ad_loading"
var isAdInit = AtomicBoolean(false)
fun initAdmobAd(activity: Activity) {
MobileAds.initialize(MyApplication.appContext) { initializationStatus ->
isAdInit.set(true)
EventUtils.event("AdmobInit", "AdmobInit")
AdmobNativeUtils.loadNativeAd()
AdmobInterstitialUtils.loadInterstitialAd(activity)
}
}
//上次展示广告时间关闭赋值,通用开屏和插页
var lastShowedOnHiddenTime = 0L
get() {
return AppPreferences.getInstance().getLong("lastShowedOnHiddenTime", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("lastShowedOnHiddenTime", value, true)
}
/**
* 通用广告条件判断
*/
fun canCommonShowAd(): Boolean {
val interval = AppPreferences.getInstance().getString("ad_interval", "10").toInt()
if (System.currentTimeMillis() - lastShowedOnHiddenTime < interval * 1000L) {
return false
}
return true
}
//上次scan展示ad时间
var lastScanShowAd = 0L
get() {
return AppPreferences.getInstance().getLong("lastScanShowAd", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("lastScanShowAd", value, true)
}
//是否显示扫描功能ad
fun isShowScanInter(): Boolean {
val interval = AppPreferences.getInstance().getString("scan_ad_interval", "10").toInt()
return System.currentTimeMillis() - lastScanShowAd > interval * 1000L
}
//上次打开文档展示ad时间
var lastOpenDocumentShowAd = 0L
get() {
return AppPreferences.getInstance().getLong("lastOpenDocumentShowAd", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("lastOpenDocumentShowAd", value, true)
}
//打开文档是否展示广告
fun isShowOpenDocumentInter(): Boolean {
val interval = AppPreferences.getInstance().getString("open_document_ad_interval", "10").toInt()
return System.currentTimeMillis() - lastOpenDocumentShowAd > interval * 1000L
}
var lastCloseDocumentShowAd = 0L
get() {
return AppPreferences.getInstance().getLong("lastCloseDocumentShowAd", field)
}
set(value) {
field = value
AppPreferences.getInstance().put("lastCloseDocumentShowAd", value, true)
}
fun isShowCloseDocumentInter(): Boolean {
val interval = AppPreferences.getInstance().getString("close_document_ad_interval", "10").toInt()
return System.currentTimeMillis() - lastCloseDocumentShowAd > interval * 1000L
}
fun isShowCloseDocument(): Boolean {
val status = AppPreferences.getInstance().getString("close_document_ad_show", "0").toInt()
return status == 1
}
fun isShowRvNativeAd(): Boolean {
val status = AppPreferences.getInstance().getString("rv_native_ad_show", "0").toInt()
return status == 1
}
fun isBackShowAd(): Boolean {
val status = AppPreferences.getInstance().getString("is_back_show_ad", "0").toInt()
return status == 1
}
}
\ No newline at end of file
import android.content.Context
import android.os.Bundle
import android.view.ViewGroup
import android.view.ViewTreeObserver
import com.base.pdfoneread.BuildConfig
import com.base.pdfoneread.ads.admob.AdmobEvent
import com.base.pdfoneread.helper.ConfigHelper
import com.base.pdfoneread.utils.AppPreferences
import com.base.pdfoneread.utils.LogEx
import com.google.ads.mediation.admob.AdMobAdapter
import com.google.android.gms.ads.AdListener
import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.AdSize
import com.google.android.gms.ads.AdView
import java.util.UUID
object AdmobBannerUtils {
private const val TAG = "AdmobBannerUtils"
private var adView: AdView? = null
private var listener: ViewTreeObserver.OnGlobalLayoutListener? = null
fun showCollapsibleBannerAd(context: Context, parent: ViewGroup, adClose: (() -> Unit)? = null) {
val isShowBanner = AppPreferences.getInstance().getString("isShowBanner", "0").toInt()
if (isShowBanner == 0) {
return
}
parent.removeAllViews()
adView?.destroy()
adView = null
adView = AdView(context)
parent.addView(adView)
adView?.onPaidEventListener = AdmobEvent.EventOnPaidEventListener(adView)
listener = ViewTreeObserver.OnGlobalLayoutListener {
val screenPixelDensity = context.resources.displayMetrics.density
val adWidth = (parent.width / screenPixelDensity).toInt()
val adSize = AdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize(context, adWidth)
adView?.adUnitId = if (BuildConfig.DEBUG) ConfigHelper.bannerAdmobIdTest else ConfigHelper.bannerAdmobId
adView?.setAdSize(adSize)
loadCollapsibleBanner(adClose)
parent.viewTreeObserver.removeOnGlobalLayoutListener(listener)
}
parent.viewTreeObserver.addOnGlobalLayoutListener(listener)
}
private fun loadCollapsibleBanner(adClose: (() -> Unit)?) {
val extras = Bundle()
extras.putString("collapsible", "bottom")
extras.putString("collapsible_request_id", UUID.randomUUID().toString())
val adRequest =
AdRequest.Builder().addNetworkExtrasBundle(AdMobAdapter::class.java, extras).build()
adView?.adListener =
object : AdListener() {
override fun onAdLoaded() {
LogEx.logDebug(TAG, "onAdLoaded")
}
override fun onAdOpened() {
LogEx.logDebug(TAG, "onAdOpened")
}
override fun onAdClosed() {
super.onAdClosed()
LogEx.logDebug(TAG, "onAdClosed")
adClose?.invoke()
}
}
adView?.loadAd(adRequest)
}
}
\ No newline at end of file
package com.base.pdfoneread.ads.admob
import android.app.Activity
import android.os.Bundle
import com.base.pdfoneread.helper.EventUtils
import com.base.pdfoneread.ui.MyApplication
import com.base.pdfoneread.utils.LogEx
import com.facebook.appevents.AppEventsConstants
import com.facebook.appevents.AppEventsLogger
import com.google.android.gms.ads.AdValue
import com.google.android.gms.ads.AdView
import com.google.android.gms.ads.OnPaidEventListener
import com.google.android.gms.ads.ResponseInfo
import com.google.android.gms.ads.appopen.AppOpenAd
import com.google.android.gms.ads.interstitial.InterstitialAd
import com.google.android.gms.ads.nativead.NativeAd
import com.google.android.gms.ads.rewarded.RewardedAd
import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.analytics.ktx.analytics
import com.google.firebase.ktx.Firebase
import org.json.JSONObject
object AdmobEvent {
private val TAG = "AdmobEvent"
fun pullAd(
responseInfo: ResponseInfo?,
adUnit: String,
error: String? = null,
reqId: String? = null
) {
val obj = JSONObject()
if (responseInfo != null) {
val response = responseInfo.adapterResponses.getOrNull(0)
if (response != null) {
obj.put("source", response.adSourceName)
val credentials = mapOf(
"placementid" to response.credentials.get("placementid"),
"appid" to response.credentials.get("appid"),
"pubid" to response.credentials.get("pubid")
)
obj.put("credentials", credentials.toString())
}
obj.put("session_id", responseInfo.responseId)
}
obj.put("networkname", responseInfo?.mediationAdapterClassName)
obj.put("ad_unit", adUnit)
obj.put("req_id", reqId)
if (error == null) {
obj.put("status", "1")
} else {
obj.put("errMsg", error)
obj.put("status", "2")
}
LogEx.logDebug(TAG, "obj=$obj")
EventUtils.event("ad_pull", ext = obj)
}
private val taichiPref by lazy {
MyApplication.appContext.getSharedPreferences("TaichiTroasCache", 0)
}
private val taichiSharedPreferencesEditor by lazy {
taichiPref.edit()
}
class EventOnPaidEventListener(private val ad: Any?) : OnPaidEventListener {
override fun onPaidEvent(adValue: AdValue) {
val valueMicros = adValue.valueMicros
val currencyCode = adValue.currencyCode
val precision = adValue.precisionType
val obj = JSONObject()
obj.put("valueMicros", valueMicros)
obj.put("currencyCode", currencyCode)
obj.put("precision", precision)
Firebase.analytics.logEvent("ad_price", Bundle().apply {
putDouble("valueMicros", valueMicros / 1000000.0)
})
val params = Bundle()
val currentImpressionRevenue = adValue.valueMicros.toDouble() / 1000000.0
params.putDouble(FirebaseAnalytics.Param.VALUE, currentImpressionRevenue)
params.putString(FirebaseAnalytics.Param.CURRENCY, "USD")
LogEx.logDebug("EventOnPaidEventListener", "precisionType=${adValue.precisionType}")
val precisionType = when (adValue.precisionType) {
0 -> "UNKNOWN"
1 -> "ESTIMATED"
2 -> "PUBLISHER_PROVIDED"
3 -> "PRECISE"
else -> "Invalid"
}
params.putString("precisionType", precisionType)
Firebase.analytics.logEvent("Ad_Impression_Revenue", params)
val previousTaichiTroasCache = taichiPref.getFloat("TaichiTroasCache", 0f)
val currentTaichiTroasCache = (previousTaichiTroasCache +
currentImpressionRevenue).toFloat()
if (currentTaichiTroasCache >= 0.01) {//如果超过0.01就触发一次tROAS taichi事件
val roasbundle = Bundle()
roasbundle.putDouble(
FirebaseAnalytics.Param.VALUE,
currentTaichiTroasCache.toDouble()
)
roasbundle.putString(FirebaseAnalytics.Param.CURRENCY, "USD")
Firebase.analytics.logEvent("Total_Ads_Revenue_001", roasbundle)
taichiSharedPreferencesEditor.putFloat("TaichiTroasCache", 0f)//重新清零,开始计算
val logger = AppEventsLogger.newLogger(MyApplication.appContext)
val parameters = Bundle()
parameters.putString(AppEventsConstants.EVENT_PARAM_CURRENCY, "USD")
logger.logEvent("ad_value", currentTaichiTroasCache.toDouble(), parameters)
} else {
taichiSharedPreferencesEditor.putFloat("TaichiTroasCache", currentTaichiTroasCache)
}
taichiSharedPreferencesEditor.commit()
var key = "ad_price"
when (ad) {
is AppOpenAd -> {
val adUnitId = ad.adUnitId
val loadedAdapterResponseInfo = ad.responseInfo.loadedAdapterResponseInfo
val adSourceName = loadedAdapterResponseInfo?.adSourceName
val adSourceId = loadedAdapterResponseInfo?.adSourceId
val adSourceInstanceName = loadedAdapterResponseInfo?.adSourceInstanceName
val adSourceInstanceId = loadedAdapterResponseInfo?.adSourceInstanceId
val sessionId = ad.responseInfo.responseId
val extras = ad.responseInfo.responseExtras
val mediationGroupName = extras.getString("mediation_group_name")
val mediationABTestName = extras.getString("mediation_ab_test_name")
val mediationABTestVariant = extras.getString("mediation_ab_test_variant")
obj.put("ad_unit", "openAd")
obj.put("adUnitId", adUnitId)
obj.put("adSourceName", adSourceName)
obj.put("adSourceId", adSourceId)
obj.put("adSourceInstanceName", adSourceInstanceName)
obj.put("adSourceInstanceId", adSourceInstanceId)
obj.put("mediationGroupName", mediationGroupName)
obj.put("mediationABTestName", mediationABTestName)
obj.put("mediationABTestVariant", mediationABTestVariant)
obj.put("session_id", sessionId)
}
is InterstitialAd -> {
val adUnitId = ad.adUnitId
val loadedAdapterResponseInfo = ad.responseInfo.loadedAdapterResponseInfo
val adSourceName = loadedAdapterResponseInfo?.adSourceName
val adSourceId = loadedAdapterResponseInfo?.adSourceId
val adSourceInstanceName = loadedAdapterResponseInfo?.adSourceInstanceName
val adSourceInstanceId = loadedAdapterResponseInfo?.adSourceInstanceId
val sessionId = ad.responseInfo.responseId
val extras = ad.responseInfo.responseExtras
val mediationGroupName = extras.getString("mediation_group_name")
val mediationABTestName = extras.getString("mediation_ab_test_name")
val mediationABTestVariant = extras.getString("mediation_ab_test_variant")
obj.put("ad_unit", "interAd")
obj.put("adUnitId", adUnitId)
obj.put("adSourceName", adSourceName)
obj.put("adSourceId", adSourceId)
obj.put("adSourceInstanceName", adSourceInstanceName)
obj.put("adSourceInstanceId", adSourceInstanceId)
obj.put("mediationGroupName", mediationGroupName)
obj.put("mediationABTestName", mediationABTestName)
obj.put("mediationABTestVariant", mediationABTestVariant)
obj.put("session_id", sessionId)
}
is RewardedAd -> {
val loadedAdapterResponseInfo = ad.responseInfo.loadedAdapterResponseInfo
val adSourceName = loadedAdapterResponseInfo?.adSourceName
val adSourceId = loadedAdapterResponseInfo?.adSourceId
val adSourceInstanceName = loadedAdapterResponseInfo?.adSourceInstanceName
val adSourceInstanceId = loadedAdapterResponseInfo?.adSourceInstanceId
val sessionId = ad.responseInfo.responseId
val extras = ad.responseInfo.responseExtras
val mediationGroupName = extras.getString("mediation_group_name")
val mediationABTestName = extras.getString("mediation_ab_test_name")
val mediationABTestVariant = extras.getString("mediation_ab_test_variant")
obj.put("adSourceName", adSourceName)
obj.put("adSourceId", adSourceId)
obj.put("adSourceInstanceName", adSourceInstanceName)
obj.put("adSourceInstanceId", adSourceInstanceId)
obj.put("mediationGroupName", mediationGroupName)
obj.put("mediationABTestName", mediationABTestName)
obj.put("mediationABTestVariant", mediationABTestVariant)
obj.put("session_id", sessionId)
}
is NativeAd -> {
key = "ad_price"
val loadedAdapterResponseInfo = ad.responseInfo?.loadedAdapterResponseInfo
val adSourceName = loadedAdapterResponseInfo?.adSourceName
val adSourceId = loadedAdapterResponseInfo?.adSourceId
val adSourceInstanceName = loadedAdapterResponseInfo?.adSourceInstanceName
val adSourceInstanceId = loadedAdapterResponseInfo?.adSourceInstanceId
val sessionId = ad.responseInfo?.responseId
val extras = ad.responseInfo?.responseExtras
val mediationGroupName = extras?.getString("mediation_group_name")
val mediationABTestName = extras?.getString("mediation_ab_test_name")
val mediationABTestVariant = extras?.getString("mediation_ab_test_variant")
obj.put("adUnitId", "nativeAd")
obj.put("adSourceName", adSourceName)
obj.put("adSourceId", adSourceId)
obj.put("adSourceInstanceName", adSourceInstanceName)
obj.put("adSourceInstanceId", adSourceInstanceId)
obj.put("mediationGroupName", mediationGroupName)
obj.put("mediationABTestName", mediationABTestName)
obj.put("mediationABTestVariant", mediationABTestVariant)
obj.put("session_id", sessionId)
}
else -> {
runCatching {
val adView = ad as AdView
val adUnitId = adView.adUnitId
val loadedAdapterResponseInfo = adView.responseInfo?.loadedAdapterResponseInfo
val adSourceName = loadedAdapterResponseInfo?.adSourceName
val adSourceId = loadedAdapterResponseInfo?.adSourceId
val adSourceInstanceName = loadedAdapterResponseInfo?.adSourceInstanceName
val adSourceInstanceId = loadedAdapterResponseInfo?.adSourceInstanceId
val sessionId = adView.responseInfo?.responseId
val extras = adView.responseInfo?.responseExtras
val mediationGroupName = extras?.getString("mediation_group_name")
val mediationABTestName = extras?.getString("mediation_ab_test_name")
val mediationABTestVariant = extras?.getString("mediation_ab_test_variant")
obj.put("ad_unit", "banner")
obj.put("adUnitId", adUnitId)
obj.put("adSourceName", adSourceName)
obj.put("adSourceId", adSourceId)
obj.put("adSourceInstanceName", adSourceInstanceName)
obj.put("adSourceInstanceId", adSourceInstanceId)
obj.put("mediationGroupName", mediationGroupName)
obj.put("mediationABTestName", mediationABTestName)
obj.put("mediationABTestVariant", mediationABTestVariant)
obj.put("session_id", sessionId)
}
}
}
EventUtils.event(key, ext = obj)
}
}
fun clickAd(responseInfo: ResponseInfo?, adUnit: String) {
val response = responseInfo?.adapterResponses?.getOrNull(0)
val obj = JSONObject()
obj.put("source", response?.adSourceName)
obj.put("ad_unit", adUnit)
val credentials = mapOf(
"placementid" to response?.credentials?.get("placementid"),
"appid" to response?.credentials?.get("appid"),
"pubid" to response?.credentials?.get("pubid")
)
obj.put("credentials", credentials.toString())
obj.put("session_id", responseInfo?.responseId)
obj.put("networkname", responseInfo?.mediationAdapterClassName)
if (adUnit != "nativeAd") {
EventUtils.event("ad_click", ext = obj)
} else {
EventUtils.event("bigimage_ad_click", ext = obj)
}
}
fun showAd(responseInfo: ResponseInfo?, adUnit: String, activity: Activity? = null) {
val response = responseInfo?.adapterResponses?.getOrNull(0)
val obj = JSONObject()
obj.put("source", response?.adSourceName)
obj.put("ad_unit", adUnit)
obj.put("networkname", responseInfo?.mediationAdapterClassName)
val credentials = mapOf(
"placementid" to response?.credentials?.get("placementid"),
"appid" to response?.credentials?.get("appid"),
"pubid" to response?.credentials?.get("pubid")
)
obj.put("credentials", credentials.toString())
obj.put("session_id", responseInfo?.responseId)
obj.put("from", activity?.javaClass?.simpleName)
if (adUnit != "nativeAd") {
EventUtils.event("ad_show", ext = obj)
} else {
EventUtils.event("ad_show", ext = obj)
}
}
}
\ No newline at end of file
package com.base.pdfoneread.ads.admob
import android.app.Activity
import android.app.Dialog
import android.widget.Toast
import com.base.pdfoneread.BuildConfig
import com.base.pdfoneread.ads.AdDialog.showAdPreparingDialog
import com.base.pdfoneread.ads.AdDisplayUtils
import com.base.pdfoneread.ads.AdmobHelper.lastShowedOnHiddenTime
import com.base.pdfoneread.ads.admob.AdmobEvent.clickAd
import com.base.pdfoneread.ads.admob.AdmobEvent.pullAd
import com.base.pdfoneread.ads.admob.AdmobEvent.showAd
import com.base.pdfoneread.helper.ConfigHelper
import com.base.pdfoneread.helper.EventUtils
import com.base.pdfoneread.ui.MyApplication
import com.google.android.gms.ads.AdError
import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.FullScreenContentCallback
import com.google.android.gms.ads.LoadAdError
import com.google.android.gms.ads.interstitial.InterstitialAd
import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback
import org.json.JSONObject
import java.util.UUID
object AdmobInterstitialUtils {
private var interAd: InterstitialAd? = null
private var interLoadTime = Long.MAX_VALUE
private var adLastDisplayTime: Long = 0
private val mRequest = AdRequest.Builder().build()
private fun isAdExpired(): Boolean {
return System.currentTimeMillis() - interLoadTime > 1000 * 60 * 60
}
fun showInterstitialAd(
activity: Activity,
isReLoadAd: Boolean = false,
isShowDialog: Boolean = true,
onHidden: ((showed: Boolean) -> Unit)? = null
) {
if (activity.isFinishing || activity.isDestroyed) {
return
}
if (isAdExpired()) {
val obj2 = JSONObject()
obj2.put("ad_unit", "interAd")
EventUtils.event("ad_expire", ext = obj2)
interAd = null
loadInterstitialAd(activity)
onHidden?.invoke(false)
return
}
if (!AdDisplayUtils.shouldShowInterAd()) {
onHidden?.invoke(false)
return
}
val obj1 = JSONObject()
obj1.put("ad_unit", "interAd")
EventUtils.event("ad_prepare_show", ext = obj1)
if (interAd != null) {
var dialog: Dialog? = null
if (!activity.isFinishing && !activity.isDestroyed) {
dialog = activity.showAdPreparingDialog()
}
displayInterstitialAd(activity, dialog, onHidden)
} else {
showAdDialogAndLoadInterstitial(activity, isReLoadAd, isShowDialog, onHidden)
}
}
fun loadInterstitialAd(activity: Activity, onLoad: (() -> Unit)? = null) {
if (interAd != null) {
onLoad?.invoke()
return
}
if (!AdDisplayUtils.shouldShowInterAd()) {
onLoad?.invoke()
return
}
val reqId = UUID.randomUUID().toString()
val obj = JSONObject()
obj.put("req_id", reqId)
obj.put("ad_type", "interAd")
obj.put("from", activity.javaClass.simpleName)
EventUtils.event("ad_pull_start", ext = obj)
InterstitialAd.load(
activity,
if (BuildConfig.DEBUG) ConfigHelper.interAdmobIdTest else ConfigHelper.interAdmobId,
mRequest,
object : InterstitialAdLoadCallback() {
override fun onAdFailedToLoad(p0: LoadAdError) {
interAd = null
onLoad?.invoke()
pullAd(p0.responseInfo, "interAd", p0.message, reqId = reqId)
if (BuildConfig.DEBUG) {
Toast.makeText(MyApplication.appContext, "拉取失败" + p0.message, Toast.LENGTH_SHORT).show()
}
}
override fun onAdLoaded(ad: InterstitialAd) {
interAd = ad
onLoad?.invoke()
interLoadTime = System.currentTimeMillis()
pullAd(ad.responseInfo, "interAd", reqId = reqId)
ad.onPaidEventListener = AdmobEvent.EventOnPaidEventListener(ad)
AdDisplayUtils.incrementInterRequestCount()
}
})
}
private fun showAdDialogAndLoadInterstitial(
activity: Activity,
isReLoadAd: Boolean,
isShowDialog: Boolean,
onHidden: ((showed: Boolean) -> Unit)?
) {
if (!isShowDialog) {
onHidden?.invoke(false)
return
}
var mDialog: Dialog? = null
if (!activity.isFinishing && !activity.isDestroyed) {
mDialog = activity.showAdPreparingDialog()
mDialog.show()
}
loadInterstitialAd(activity) {
mDialog?.dismiss()
if (!isReLoadAd) {
showInterstitialAd(activity, true, false) {
onHidden?.invoke(it)
}
}
}
if (isReLoadAd) {
mDialog?.dismiss()
onHidden?.invoke(false)
}
}
private fun displayInterstitialAd(
activity: Activity,
dialog: Dialog? = null,
onHidden: ((showed: Boolean) -> Unit)? = null
) {
val thisInterAd = interAd
interAd = null
thisInterAd?.fullScreenContentCallback = object : FullScreenContentCallback() {
override fun onAdClicked() {
clickAd(thisInterAd?.responseInfo, "interAd")
AdDisplayUtils.incrementInterClickCount()
}
override fun onAdDismissedFullScreenContent() {
dialog?.dismiss()
interAd = null
onHidden?.invoke(true)
loadInterstitialAd(activity)
lastShowedOnHiddenTime = System.currentTimeMillis()
}
override fun onAdFailedToShowFullScreenContent(p0: AdError) {
dialog?.dismiss()
interAd = null
onHidden?.invoke(false)
loadInterstitialAd(activity)
}
override fun onAdShowedFullScreenContent() {
dialog?.dismiss()
showAd(thisInterAd?.responseInfo, "interAd", activity)
AdDisplayUtils.incrementInterShowCount()
adLastDisplayTime = System.currentTimeMillis() / 1000
}
}
thisInterAd?.show(activity)
}
fun haveReadAd(): Boolean {
return interAd != null
}
}
\ No newline at end of file
package com.base.pdfoneread.ads.admob
import android.app.Activity
import android.view.ViewGroup
import androidx.core.view.isVisible
import com.base.pdfoneread.BuildConfig
import com.base.pdfoneread.R
import com.base.pdfoneread.ads.AdDisplayUtils
import com.base.pdfoneread.ads.admob.AdmobEvent.clickAd
import com.base.pdfoneread.ads.admob.AdmobEvent.pullAd
import com.base.pdfoneread.ads.admob.AdmobEvent.showAd
import com.base.pdfoneread.helper.ConfigHelper
import com.base.pdfoneread.helper.EventUtils
import com.base.pdfoneread.ui.MyApplication
import com.base.pdfoneread.utils.LogEx
import com.google.android.gms.ads.AdListener
import com.google.android.gms.ads.AdLoader
import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.LoadAdError
import com.google.android.gms.ads.nativead.NativeAd
import org.json.JSONObject
import java.util.UUID
object AdmobNativeUtils {
private const val TAG = "AdmobNativeUtils"
private var nativeAd: NativeAd? = null
private var isLoading = false
private var nativeLoadTime = Long.MAX_VALUE
private var loadingListener: (() -> Unit)? = null
private val mRequest = AdRequest.Builder().build()
var onAdLoaded: (() -> Unit)? = null
fun loadNativeAd() {
if (nativeAd != null) {
return
}
if (isLoading) {
return
}
isLoading = true
if (!AdDisplayUtils.shouldShowNative()) {
return
}
val reqId = UUID.randomUUID().toString()
val obj = JSONObject()
obj.put("req_id", reqId)
obj.put("ad_type", "nativeAd")
val adLoader = AdLoader.Builder(
MyApplication.appContext,
if (BuildConfig.DEBUG) ConfigHelper.nativeAdmobIdTest else ConfigHelper.nativeAdmobId
).forNativeAd {
nativeLoadTime = System.currentTimeMillis()
nativeAd = it
it.setOnPaidEventListener(AdmobEvent.EventOnPaidEventListener(it))
LogEx.logDebug(TAG, "nativeAd=${nativeAd.toString()}")
isLoading = false
loadingListener?.invoke()
loadingListener = null
pullAd(it.responseInfo, "nativeAd", reqId = reqId)
}.withAdListener(object : AdListener() {
override fun onAdLoaded() {
super.onAdLoaded()
onAdLoaded?.invoke()
onAdLoaded = null
AdDisplayUtils.incrementNativeRequestCount()
}
override fun onAdClicked() {
clickAd(nativeAd?.responseInfo, "nativeAd")
AdDisplayUtils.incrementNativeClickCount()
}
override fun onAdFailedToLoad(p0: LoadAdError) {
LogEx.logDebug(TAG, "onAdFailedToLoad=${p0.message}")
nativeAd = null
isLoading = false
pullAd(p0.responseInfo, "nativeAd", p0.message, reqId = reqId)
// Log.e("MXL", "NativeAdFailedToLoad: " + p0.message)
}
}).build()
adLoader.loadAd(mRequest)
}
fun showNativeAd(activity: Activity?, parent: ViewGroup, layout: Int = R.layout.layout_admob_native_custom) {
val obj = JSONObject()
obj.put("ad_unit", "nativeAd")
EventUtils.event("ad_prepare_show", ext = obj)
if (!AdDisplayUtils.shouldShowNative()) {
return
}
loadingListener = {
if (System.currentTimeMillis() - nativeLoadTime <= 1000 * 60 * 60) {
nativeAd?.let {
NativeView(parent.context, layout).run {
parent.removeAllViews()
setNativeAd(it)
parent.addView(this)
parent.isVisible = true
showAd(nativeAd?.responseInfo, "nativeAd", activity)
}
}
}
nativeAd = null
loadNativeAd()
}
if (nativeAd == null) {
loadNativeAd()
val obj2 = JSONObject()
obj2.put("reason", "no_ad")
obj2.put("ad_unit", "nativeAd")
EventUtils.event("ad_show_error", ext = obj2)
} else {
loadingListener?.invoke()
loadingListener = null
}
}
fun showReadyNativeAd(
activity: Activity?,
readyNativeAd: NativeAd?,
parent: ViewGroup,
layout: Int = R.layout.layout_admob_native_custom
) {
readyNativeAd?.let {
NativeView(parent.context, layout).run {
parent.removeAllViews()
setNativeAd(it)
parent.addView(this)
parent.isVisible = true
showAd(nativeAd?.responseInfo, "nativeAd", activity)
}
}
}
fun onDestroy() {
nativeAd?.destroy()
nativeAd = null
}
}
\ No newline at end of file
package com.base.pdfoneread.ads.admob
import android.app.Activity
import com.base.pdfoneread.BuildConfig
import com.base.pdfoneread.ads.AdDisplayUtils
import com.base.pdfoneread.ads.AdmobHelper.lastShowedOnHiddenTime
import com.base.pdfoneread.ads.admob.AdmobEvent.clickAd
import com.base.pdfoneread.ads.admob.AdmobEvent.pullAd
import com.base.pdfoneread.ads.admob.AdmobEvent.showAd
import com.base.pdfoneread.helper.ConfigHelper
import com.base.pdfoneread.helper.EventUtils
import com.base.pdfoneread.ui.MyApplication
import com.base.pdfoneread.utils.LogEx
import com.google.android.gms.ads.AdError
import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.FullScreenContentCallback
import com.google.android.gms.ads.LoadAdError
import com.google.android.gms.ads.appopen.AppOpenAd
import org.json.JSONObject
import java.util.UUID
object AdmobOpenUtils {
private const val TAG = "AdmobOpenUtils"
private val mRequest = AdRequest.Builder().build()
private var openLoadTime = Long.MAX_VALUE
private var mOpenAd: AppOpenAd? = null
private fun isAdExpired(): Boolean {
return System.currentTimeMillis() - openLoadTime > 1000 * 60 * 60
}
fun haveReadAd(): Boolean {
return mOpenAd != null
}
fun loadAppOpenAd(onLoad: ((loaded: Boolean) -> Unit)? = null) {
if (mOpenAd != null) {
onLoad?.invoke(true)
return
}
if (!AdDisplayUtils.shouldShowOpenAd()) {
onLoad?.invoke(false)
return
}
val reqId = UUID.randomUUID().toString()
val obj = JSONObject()
obj.put("req_id", reqId)
obj.put("ad_type", "openAd")
EventUtils.event("ad_pull_start", ext = obj)
AppOpenAd.load(
MyApplication.appContext,
if (BuildConfig.DEBUG) ConfigHelper.openAdmobIdTest else ConfigHelper.openAdmobId,
mRequest,
object : AppOpenAd.AppOpenAdLoadCallback() {
override fun onAdLoaded(ad: AppOpenAd) {
LogEx.logDebug(TAG, "onAdLoaded")
openLoadTime = System.currentTimeMillis()
mOpenAd = ad
onLoad?.invoke(true)
pullAd(ad.responseInfo, "openAd", reqId = reqId)
ad.onPaidEventListener = AdmobEvent.EventOnPaidEventListener(ad)
AdDisplayUtils.incrementOpenRequestCount()
}
override fun onAdFailedToLoad(p0: LoadAdError) {
LogEx.logDebug(TAG, "LoadAdError ${p0.message}")
mOpenAd = null
onLoad?.invoke(false)
pullAd(p0.responseInfo, "openAd", p0.message, reqId = reqId)
}
})
}
fun showAppOpenAd(
activity: Activity,
isRetry: Boolean = false,
showBefore: ((flag: Boolean) -> Unit)? = null,
onHidden: ((showed: Boolean) -> Unit)? = null
) {
if (activity.isFinishing || activity.isDestroyed) {
LogEx.logDebug(TAG, "activity isDestroyed")
return
}
if (!AdDisplayUtils.shouldShowOpenAd()) {
onHidden?.invoke(false)
return
}
if (isAdExpired()) {
LogEx.logDebug(TAG, "openLoadTime out time")
mOpenAd = null
loadAppOpenAd()
onHidden?.invoke(false)
val obj2 = JSONObject()
obj2.put("ad_unit", "openAd")
EventUtils.event("ad_expire", ext = obj2)
return
}
if (!isRetry) {
val obj1 = JSONObject()
obj1.put("ad_unit", "openAd")
EventUtils.event("ad_prepare_show", ext = obj1)
LogEx.logDebug(TAG, "open ad_prepare_show")
}
if (mOpenAd != null) {
LogEx.logDebug(TAG, "mOpenAd!=null")
val thisMOpenAd = mOpenAd
mOpenAd = null
thisMOpenAd?.fullScreenContentCallback = object : FullScreenContentCallback() {
override fun onAdClicked() {
clickAd(thisMOpenAd?.responseInfo, "openAd")
AdDisplayUtils.incrementClickShow()
}
override fun onAdDismissedFullScreenContent() {
mOpenAd = null
onHidden?.invoke(true)
loadAppOpenAd()
lastShowedOnHiddenTime = System.currentTimeMillis()
}
override fun onAdFailedToShowFullScreenContent(p0: AdError) {
mOpenAd = null
onHidden?.invoke(false)
loadAppOpenAd()
val obj = JSONObject()
obj.put("reason", p0.message)
obj.put("code", p0.code)
obj.put("ad_unit", "openAd")
EventUtils.event("ad_show_error", ext = obj)
}
override fun onAdShowedFullScreenContent() {
showBefore?.invoke(true)
showAd(thisMOpenAd?.responseInfo, "openAd", activity)
AdDisplayUtils.incrementOpenShow()
}
}
thisMOpenAd?.show(activity)
} else {
LogEx.logDebug(TAG, "mOpenAd=null")
loadAppOpenAd {
if (mOpenAd != null) {
showAppOpenAd(activity, true, showBefore, onHidden)
} else {
val obj = JSONObject()
obj.put("reason", "no_ad")
obj.put("ad_unit", "openAd")
EventUtils.event("ad_show_error", ext = obj)
onHidden?.invoke(false)
}
}
}
}
}
\ No newline at end of file
package com.base.pdfoneread.ads.admob
import android.annotation.SuppressLint
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.TextView
import com.base.pdfoneread.R
import com.google.android.gms.ads.nativead.NativeAd
import com.google.android.gms.ads.nativead.NativeAdView
@SuppressLint("ViewConstructor")
class NativeView(context: Context, val layout: Int, attrs: AttributeSet? = null) : FrameLayout(context, attrs) {
init {
layoutParams = LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
}
fun setNativeAd(nativeAd: NativeAd?) {
nativeAd ?: return
val adView = LayoutInflater.from(context)
.inflate(layout, this, false) as NativeAdView
adView.mediaView = adView.findViewById(R.id.ad_media)
adView.headlineView = adView.findViewById(R.id.ad_headline)
adView.bodyView = adView.findViewById(R.id.ad_body)
adView.callToActionView = adView.findViewById(R.id.ad_call_to_action)
adView.iconView = adView.findViewById(R.id.ad_app_icon)
(adView.headlineView as TextView?)?.text = nativeAd.headline
adView.mediaView?.mediaContent = nativeAd.mediaContent
if (nativeAd.body == null) {
adView.bodyView?.visibility = View.INVISIBLE
} else {
adView.bodyView?.visibility = View.VISIBLE
(adView.bodyView as TextView?)?.text = nativeAd.body
}
if (nativeAd.callToAction == null) {
adView.callToActionView?.visibility = View.INVISIBLE
} else {
adView.callToActionView?.visibility = View.VISIBLE
(adView.callToActionView as Button?)?.text = nativeAd.callToAction
}
if (nativeAd.icon == null) {
adView.iconView?.visibility = View.GONE
} else {
(adView.iconView as ImageView?)?.setImageDrawable(
nativeAd.icon?.drawable
)
adView.iconView?.visibility = View.VISIBLE
}
adView.setNativeAd(nativeAd)
removeAllViews()
addView(adView)
}
}
\ No newline at end of file
package com.base.pdfoneread.helper
import android.os.Build
import com.base.pdfoneread.BuildConfig
import com.base.pdfoneread.bean.ConstObject.ifAgreePrivacy
import com.base.pdfoneread.helper.ReportUtils.doPost
import com.base.pdfoneread.utils.AppPreferences
import com.base.pdfoneread.utils.LogEx
import org.json.JSONException
import org.json.JSONObject
object EventUtils {
private val TAG = "EventUtils"
fun event(
key: String,
value: String? = null,
ext: JSONObject? = null,
isSingleEvent: Boolean = false
) {
if (!ifAgreePrivacy) {
return
}
if (isSingleEvent) {
val stringSet = AppPreferences.getInstance().getStringSet("singleEvent", setOf())
if (stringSet.contains(key)) {
return
}
}
Thread {
var paramJson: String? = ""
try {
val pkg = ConfigHelper.packageName
val s = JSONObject()
.put("action", key)
.put("value", value)
.put("ext", ext)
val s2 = JSONObject()
.put("${pkg}_3", AppPreferences.getInstance().getString("Equipment", ""))
.put("${pkg}_4", AppPreferences.getInstance().getString("Manufacturer", ""))
.put("${pkg}_5", Build.VERSION.SDK_INT)
.put("${pkg}_9", AppPreferences.getInstance().getString("uuid", ""))
.put("${pkg}_10", AppPreferences.getInstance().getString("gid", ""))
.put("${pkg}_13", "android")
.put("${pkg}_15", "google")
.put("${pkg}_14", BuildConfig.VERSION_CODE)
.put("${pkg}_8", BuildConfig.VERSION_NAME)
.put("${pkg}_24", BuildConfig.BUILD_TYPE)
val data = JSONObject()
.put("data", s)
.put("bp", s2)
.toString()
LogEx.logDebug(TAG, "uuid=${AppPreferences.getInstance().getString("uuid", "")}")
LogEx.logDebug(TAG, "gid=${AppPreferences.getInstance().getString("gid", "")}")
paramJson = AESHelper.encrypt(data)
} catch (e: JSONException) {
paramJson = ""
}
LogEx.logDebug(TAG, "url=$url")
doPost(
url,
HashMap(),
paramJson
)
}.start()
}
private val url by lazy {
val pkg = ConfigHelper.packageName
val url = StringBuilder(
"${ConfigHelper.eventUrl}/${
pkg.filter { it.isLowerCase() }.substring(4, 9)
}sp"
)
url.append("?pkg=$pkg")
url.toString()
}
}
\ No newline at end of file
package com.base.pdfoneread.ui.document package com.base.pdfoneread.ui.document
import android.graphics.Color
import androidx.core.view.updatePadding
import androidx.lifecycle.lifecycleScope
import com.base.pdfoneread.R
import com.base.pdfoneread.bean.DocumentBean.Companion.TYPE_ALL
import com.base.pdfoneread.bean.DocumentBean.Companion.TYPE_EXCEL
import com.base.pdfoneread.bean.DocumentBean.Companion.TYPE_PDF
import com.base.pdfoneread.bean.DocumentBean.Companion.TYPE_PPT
import com.base.pdfoneread.bean.DocumentBean.Companion.TYPE_WORD
import com.base.pdfoneread.databinding.ActivityDocumentBinding import com.base.pdfoneread.databinding.ActivityDocumentBinding
import com.base.pdfoneread.ui.BaseActivity import com.base.pdfoneread.ui.BaseActivity
import com.base.pdfoneread.utils.BarUtils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
class DocumentActivity : BaseActivity<ActivityDocumentBinding>() { class DocumentActivity : BaseActivity<ActivityDocumentBinding>() {
...@@ -12,7 +24,51 @@ class DocumentActivity : BaseActivity<ActivityDocumentBinding>() { ...@@ -12,7 +24,51 @@ class DocumentActivity : BaseActivity<ActivityDocumentBinding>() {
} }
override fun initView() { override fun initView() {
BarUtils.setStatusBarLightMode(this, true)
BarUtils.setStatusBarColor(this, Color.WHITE)
binding.root.updatePadding(top = BarUtils.getStatusBarHeight())
type = intent.extras?.getString("type") ?: "" type = intent.extras?.getString("type") ?: ""
when (type) {
TYPE_ALL -> {
binding.tvTittle.text = getString(R.string.all_files)
}
TYPE_PDF -> {
binding.tvTittle.text = getString(R.string.pdf_files)
}
TYPE_WORD -> {
binding.tvTittle.text = getString(R.string.word_files)
}
TYPE_EXCEL -> {
binding.tvTittle.text = getString(R.string.excel_files)
}
TYPE_PPT -> {
binding.tvTittle.text = getString(R.string.ppt_files)
}
}
}
override fun initListener() {
super.initListener()
initData()
}
private fun initData() = lifecycleScope.launch(Dispatchers.IO) {
val list = when (type) {
TYPE_ALL -> getAllDocument(this@DocumentActivity)
else -> getAllDocument(this@DocumentActivity)
}
if (list.isEmpty()) {
} else {
}
} }
} }
\ No newline at end of file
package com.base.pdfoneread.ui.document
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.base.pdfoneread.R
import com.base.pdfoneread.bean.DocumentBean
import com.base.pdfoneread.bean.DocumentBean.Companion.TYPE_EXCEL
import com.base.pdfoneread.bean.DocumentBean.Companion.TYPE_PDF
import com.base.pdfoneread.bean.DocumentBean.Companion.TYPE_PPT
import com.base.pdfoneread.bean.DocumentBean.Companion.TYPE_WORD
import com.base.pdfoneread.databinding.ItemAdBinding
import com.base.pdfoneread.databinding.ItemDocumentBinding
import com.base.pdfoneread.utils.KotlinExt.toFormatSize
import com.base.pdfoneread.utils.KotlinExt.toFormatTime5
import com.base.pdfoneread.utils.LogEx
import com.base.pdfoneread.utils.XmlEx.inflate
import com.chad.library.adapter4.BaseQuickAdapter
import java.io.File
class DocumentAdapter(
val activity: Activity
) : BaseQuickAdapter<DocumentBean, DocumentAdapter.DocumentViewHolder>() {
private val TAG = "DocumentAdapter"
inner class DocumentViewHolder(view: View) : ViewHolder(view)
var moreAction: ((item: DocumentBean) -> Unit)? = null
var itemClickAction: ((item: DocumentBean) -> Unit)? = null
@SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder: DocumentViewHolder, position: Int, item: DocumentBean?) {
item ?: return
if (item.isAd) {
val binding = ItemAdBinding.bind(holder.itemView)
// AdmobNativeUtils.showNativeAd(activity, binding.flAd, R.layout.layout_admob_document)
} else {
val binding = ItemDocumentBinding.bind(holder.itemView)
when (item.type) {
TYPE_PDF -> {
LogEx.logDebug(TAG, "pdf state = ${item.state}")
if (item.state == 0) {
binding.ivIcon.setImageResource(R.mipmap.rv_pdf)
} else {
// binding.ivIcon.setImageResource(R.mipmap.rv_pdf_lock)
}
}
TYPE_WORD -> {
binding.ivIcon.setImageResource(R.mipmap.rv_word)
}
TYPE_EXCEL -> {
binding.ivIcon.setImageResource(R.mipmap.rv_excel)
}
TYPE_PPT -> {
binding.ivIcon.setImageResource(R.mipmap.rv_ppt)
}
}
val file = File(item.path)
binding.tvName.text = file.name
binding.tvInfo.text = file.lastModified().toFormatTime5() + " " + file.length().toFormatSize()
binding.flMore.setOnClickListener {
moreAction?.invoke(item)
}
binding.root.setOnClickListener {
itemClickAction?.invoke(item)
}
}
}
override fun getItemViewType(position: Int, list: List<DocumentBean>): Int {
val item = list[position]
return if (item.isAd) 1 else 0
}
override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): DocumentViewHolder {
return if (viewType == 0) {
DocumentViewHolder(R.layout.item_document.inflate(parent))
} else {
DocumentViewHolder(R.layout.item_ad.inflate(parent))
}
}
}
\ No newline at end of file
//package com.base.pdfoneread.ui.document package com.base.pdfoneread.ui.document
//
//import android.content.Context import android.content.Context
//import android.media.MediaScannerConnection import android.media.MediaScannerConnection
//import android.net.Uri import android.net.Uri
//import android.os.Environment import android.os.Environment
//import com.base.pdfoneread.ui.MyApplication.Companion.appContext import com.base.pdfoneread.ui.MyApplication.Companion.appContext
//import com.base.pdfoneread.bean.ConstObject import com.base.pdfoneread.bean.ConstObject
//import com.base.pdfoneread.bean.ConstObject.MIME_TYPE_DOC import com.base.pdfoneread.bean.ConstObject.MIME_TYPE_DOC
//import com.base.pdfoneread.bean.ConstObject.MIME_TYPE_DOCX import com.base.pdfoneread.bean.ConstObject.MIME_TYPE_DOCX
//import com.base.pdfoneread.bean.ConstObject.MIME_TYPE_PDF import com.base.pdfoneread.bean.ConstObject.MIME_TYPE_PDF
//import com.base.pdfoneread.bean.ConstObject.MIME_TYPE_PPT import com.base.pdfoneread.bean.ConstObject.MIME_TYPE_PPT
//import com.base.pdfoneread.bean.ConstObject.MIME_TYPE_PPTX import com.base.pdfoneread.bean.ConstObject.MIME_TYPE_PPTX
//import com.base.pdfoneread.bean.ConstObject.MIME_TYPE_XLS import com.base.pdfoneread.bean.ConstObject.MIME_TYPE_XLS
//import com.base.pdfoneread.bean.ConstObject.MIME_TYPE_XLSX import com.base.pdfoneread.bean.ConstObject.MIME_TYPE_XLSX
//import com.base.pdfoneread.bean.DocumentBean import com.base.pdfoneread.bean.DocumentBean
//import com.base.pdfoneread.bean.DocumentBean.Companion.TYPE_EXCEL import com.base.pdfoneread.bean.DocumentBean.Companion.TYPE_EXCEL
//import com.base.pdfoneread.bean.DocumentBean.Companion.TYPE_PDF import com.base.pdfoneread.bean.DocumentBean.Companion.TYPE_PDF
//import com.base.pdfoneread.bean.DocumentBean.Companion.TYPE_PPT import com.base.pdfoneread.bean.DocumentBean.Companion.TYPE_PPT
//import com.base.pdfoneread.bean.DocumentBean.Companion.TYPE_WORD import com.base.pdfoneread.bean.DocumentBean.Companion.TYPE_WORD
//import com.base.pdfoneread.utils.AssetUtils.readByteArrayFromAsset import com.base.pdfoneread.bean.MediaBean
//import com.base.pdfoneread.utils.getMediaFile import com.base.pdfoneread.utils.AssetUtils.readByteArrayFromAsset
//import java.io.File import com.base.pdfoneread.utils.PdfBoxUtils.checkPdfEncryption
//import java.io.FileOutputStream import com.base.pdfoneread.utils.SpStringUtils
//import java.io.IOException import com.base.pdfoneread.utils.SpStringUtils.BOOKMARK_KEY
// import com.base.pdfoneread.utils.getMediaFile
//fun Context.upDateDemoStore() { import java.io.File
// val demoFile = File(filesDir, "demo") import java.io.FileOutputStream
// MediaScannerConnection.scanFile( import java.io.IOException
// this, arrayOf(demoFile.absolutePath), null
// ) { path: String?, uri: Uri? -> } fun Context.upDateDemoStore() {
//} val demoFile = File(filesDir, "demo")
// MediaScannerConnection.scanFile(
//fun getDocumentAppDir(): File { this, arrayOf(demoFile.absolutePath), null
// val appDir = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS), appContext.packageName) ) { path: String?, uri: Uri? -> }
// if (!appDir.exists()) }
// appDir.exists()
// return appDir fun getDocumentAppDir(): File {
//} val appDir = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS), appContext.packageName)
// if (!appDir.exists())
//fun Context.saveAssetsFile() { appDir.exists()
// val demoFile = File(filesDir, "demo") return appDir
// demoFile.mkdirs() }
// arrayOf(
// "DEMO.pdf", fun Context.saveAssetsFile() {
// "DEMO.docx", val demoFile = File(filesDir, "demo")
// "DEMO.xlsx", demoFile.mkdirs()
// "DEMO.pptx" arrayOf(
// ).forEach { "DEMO.pdf",
// "DEMO.docx",
// val file = File(demoFile, it) "DEMO.xlsx",
// if (file.exists() && file.length() != 0L) { "DEMO.pptx"
// return ).forEach {
// }
// file.createNewFile() val file = File(demoFile, it)
// if (file.exists() && file.length() != 0L) {
// try { return
// FileOutputStream(file).use { fos -> fos.write(readByteArrayFromAsset(it)) } }
// } catch (e: IOException) { file.createNewFile()
// e.printStackTrace()
// } try {
// FileOutputStream(file).use { fos -> fos.write(readByteArrayFromAsset(it)) }
// } } catch (e: IOException) {
//} e.printStackTrace()
// }
//fun getPdfDemo(context: Context): DocumentBean {
// val demoDocumentBean = DocumentBean() }
// demoDocumentBean.type = TYPE_PDF }
// val demoFile = File(context.filesDir, "demo")
// demoDocumentBean.path = demoFile.listFiles()?.find { it.name.contains(".pdf") }?.absolutePath ?: "" fun getPdfDemo(context: Context): DocumentBean {
// context.pdfCheck(demoDocumentBean) val demoDocumentBean = DocumentBean()
// return demoDocumentBean demoDocumentBean.type = TYPE_PDF
//} val demoFile = File(context.filesDir, "demo")
// demoDocumentBean.path = demoFile.listFiles()?.find { it.name.contains(".pdf") }?.absolutePath ?: ""
//fun getWordDemo(context: Context): DocumentBean { context.pdfCheck(demoDocumentBean)
// val demoDocumentBean = DocumentBean() return demoDocumentBean
// demoDocumentBean.type = TYPE_WORD }
// val demoFile = File(context.filesDir, "demo")
// demoDocumentBean.path = demoFile.listFiles()?.find { it.name.contains(".docx") }?.absolutePath ?: "" fun getWordDemo(context: Context): DocumentBean {
// return demoDocumentBean val demoDocumentBean = DocumentBean()
//} demoDocumentBean.type = TYPE_WORD
// val demoFile = File(context.filesDir, "demo")
//fun getExcelDemo(context: Context): DocumentBean { demoDocumentBean.path = demoFile.listFiles()?.find { it.name.contains(".docx") }?.absolutePath ?: ""
// val demoDocumentBean = DocumentBean() return demoDocumentBean
// demoDocumentBean.type = TYPE_EXCEL }
// val demoFile = File(context.filesDir, "demo")
// demoDocumentBean.path = demoFile.listFiles()?.find { it.name.contains(".xlsx") }?.absolutePath ?: "" fun getExcelDemo(context: Context): DocumentBean {
// return demoDocumentBean val demoDocumentBean = DocumentBean()
//} demoDocumentBean.type = TYPE_EXCEL
// val demoFile = File(context.filesDir, "demo")
//fun getPPtDemo(context: Context): DocumentBean { demoDocumentBean.path = demoFile.listFiles()?.find { it.name.contains(".xlsx") }?.absolutePath ?: ""
// val demoDocumentBean = DocumentBean() return demoDocumentBean
// demoDocumentBean.type = TYPE_PPT }
// val demoFile = File(context.filesDir, "demo")
// demoDocumentBean.path = demoFile.listFiles()?.find { it.name.contains(".pptx") }?.absolutePath ?: "" fun getPPtDemo(context: Context): DocumentBean {
// return demoDocumentBean val demoDocumentBean = DocumentBean()
//} demoDocumentBean.type = TYPE_PPT
// val demoFile = File(context.filesDir, "demo")
//fun getAllDocument(context: Context): MutableList<DocumentBean> { demoDocumentBean.path = demoFile.listFiles()?.find { it.name.contains(".pptx") }?.absolutePath ?: ""
// context.upDateDemoStore() return demoDocumentBean
// if (!ConstObject.haveSaveDemo) { }
// context.saveAssetsFile()
// ConstObject.haveSaveDemo = true fun getAllDocument(context: Context): MutableList<DocumentBean> {
// } context.upDateDemoStore()
// if (!ConstObject.haveSaveDemo) {
// context.saveAssetsFile()
// val selectionArgs = arrayOf( ConstObject.haveSaveDemo = true
// MIME_TYPE_PDF, }
// MIME_TYPE_DOC,
// MIME_TYPE_DOCX,
// MIME_TYPE_XLS, val selectionArgs = arrayOf(
// MIME_TYPE_XLSX, MIME_TYPE_PDF,
// MIME_TYPE_PPT, MIME_TYPE_DOC,
// MIME_TYPE_PPTX, MIME_TYPE_DOCX,
// ) MIME_TYPE_XLS,
// MIME_TYPE_XLSX,
// val list = context.getMediaFile(selectionArgs = selectionArgs) MIME_TYPE_PPT,
// val documentList = list.map { MIME_TYPE_PPTX,
// val documentBean = DocumentBean(it.path, uri = it.uri, type = getDocumentType(it)) )
// if (documentBean.type == TYPE_PDF) {
// context.pdfCheck(documentBean) val list = context.getMediaFile(selectionArgs = selectionArgs)
// } val documentList = list.map {
// documentBean val documentBean = DocumentBean(it.path, uri = it.uri, type = getDocumentType(it))
// } if (documentBean.type == TYPE_PDF) {
// val new = documentList.toMutableList() context.pdfCheck(documentBean)
// val pptDemo = getPPtDemo(context) }
// if (File(pptDemo.path).exists()) { documentBean
// new.add(0, pptDemo) }
// } val new = documentList.toMutableList()
// val excelDemo = getExcelDemo(context) val pptDemo = getPPtDemo(context)
// if (File(excelDemo.path).exists()) { if (File(pptDemo.path).exists()) {
// new.add(0, excelDemo) new.add(0, pptDemo)
// } }
// val wordDemp = getWordDemo(context) val excelDemo = getExcelDemo(context)
// if (File(wordDemp.path).exists()) { if (File(excelDemo.path).exists()) {
// new.add(0, wordDemp) new.add(0, excelDemo)
// } }
// val pdfDemo = getPdfDemo(context) val wordDemp = getWordDemo(context)
// if (File(pdfDemo.path).exists()) { if (File(wordDemp.path).exists()) {
// new.add(0, pdfDemo) new.add(0, wordDemp)
// } }
// return new val pdfDemo = getPdfDemo(context)
//} if (File(pdfDemo.path).exists()) {
// new.add(0, pdfDemo)
//fun getPdfFastSize(context: Context): Int { }
// val selectionArgs = arrayOf( return new
// MIME_TYPE_PDF }
// )
// val list = context.getMediaFile(selectionArgs = selectionArgs) fun getPdfFastSize(context: Context): Int {
// var size = list.size val selectionArgs = arrayOf(
// val pdfDemo = getPdfDemo(context) MIME_TYPE_PDF
// if (File(pdfDemo.path).exists()) { )
// size += 1 val list = context.getMediaFile(selectionArgs = selectionArgs)
// } var size = list.size
// return size val pdfDemo = getPdfDemo(context)
//} if (File(pdfDemo.path).exists()) {
// size += 1
//fun getPdfDocument(context: Context): MutableList<DocumentBean> { }
// if (!ConstObject.haveSaveDemo) { return size
// context.saveAssetsFile() }
// ConstObject.haveSaveDemo = true
// } fun getPdfDocument(context: Context): MutableList<DocumentBean> {
// val selectionArgs = arrayOf( if (!ConstObject.haveSaveDemo) {
// MIME_TYPE_PDF context.saveAssetsFile()
// ) ConstObject.haveSaveDemo = true
// val list = context.getMediaFile(selectionArgs = selectionArgs) }
// val documentList = list.map { val selectionArgs = arrayOf(
// val demoDocumentBean = DocumentBean(it.path, uri = it.uri, type = TYPE_PDF) MIME_TYPE_PDF
// context.pdfCheck(demoDocumentBean) )
// demoDocumentBean val list = context.getMediaFile(selectionArgs = selectionArgs)
// } val documentList = list.map {
// val new = documentList.toMutableList() val demoDocumentBean = DocumentBean(it.path, uri = it.uri, type = TYPE_PDF)
// val pdfDemo = getPdfDemo(context) context.pdfCheck(demoDocumentBean)
// if (File(pdfDemo.path).exists()) { demoDocumentBean
// new.add(0, pdfDemo) }
// } val new = documentList.toMutableList()
// return new val pdfDemo = getPdfDemo(context)
//} if (File(pdfDemo.path).exists()) {
// new.add(0, pdfDemo)
//fun getWordDocument(context: Context): MutableList<DocumentBean> { }
// if (!ConstObject.haveSaveDemo) { return new
// context.saveAssetsFile() }
// ConstObject.haveSaveDemo = true
// } fun getWordDocument(context: Context): MutableList<DocumentBean> {
// val selectionArgs = arrayOf( if (!ConstObject.haveSaveDemo) {
// MIME_TYPE_DOC, context.saveAssetsFile()
// MIME_TYPE_DOCX, ConstObject.haveSaveDemo = true
// ) }
// val list = context.getMediaFile(selectionArgs = selectionArgs) val selectionArgs = arrayOf(
// val documentList = list.map { MIME_TYPE_DOC,
// DocumentBean(it.path, uri = it.uri, type = TYPE_WORD) MIME_TYPE_DOCX,
// } )
// val new = documentList.toMutableList() val list = context.getMediaFile(selectionArgs = selectionArgs)
// val wordDemo = getWordDemo(context) val documentList = list.map {
// if (File(wordDemo.path).exists()) { DocumentBean(it.path, uri = it.uri, type = TYPE_WORD)
// new.add(0, wordDemo) }
// } val new = documentList.toMutableList()
// return new val wordDemo = getWordDemo(context)
//} if (File(wordDemo.path).exists()) {
// new.add(0, wordDemo)
//fun getExcelDocument(context: Context): MutableList<DocumentBean> { }
// if (!ConstObject.haveSaveDemo) { return new
// context.saveAssetsFile() }
// ConstObject.haveSaveDemo = true
// } fun getExcelDocument(context: Context): MutableList<DocumentBean> {
// val selectionArgs = arrayOf( if (!ConstObject.haveSaveDemo) {
// MIME_TYPE_XLS, context.saveAssetsFile()
// MIME_TYPE_XLSX, ConstObject.haveSaveDemo = true
// ) }
// val list = context.getMediaFile(selectionArgs = selectionArgs) val selectionArgs = arrayOf(
// val documentList = list.map { MIME_TYPE_XLS,
// DocumentBean(it.path, uri = it.uri, type = TYPE_EXCEL) MIME_TYPE_XLSX,
// } )
// val new = documentList.toMutableList() val list = context.getMediaFile(selectionArgs = selectionArgs)
// val excelDemo = getExcelDemo(context) val documentList = list.map {
// if (File(excelDemo.path).exists()) { DocumentBean(it.path, uri = it.uri, type = TYPE_EXCEL)
// new.add(0, excelDemo) }
// } val new = documentList.toMutableList()
// return new val excelDemo = getExcelDemo(context)
//} if (File(excelDemo.path).exists()) {
// new.add(0, excelDemo)
//fun getPptDocument(context: Context): MutableList<DocumentBean> { }
// if (!ConstObject.haveSaveDemo) { return new
// context.saveAssetsFile() }
// ConstObject.haveSaveDemo = true
// } fun getPptDocument(context: Context): MutableList<DocumentBean> {
// val selectionArgs = arrayOf( if (!ConstObject.haveSaveDemo) {
// MIME_TYPE_PPT, context.saveAssetsFile()
// MIME_TYPE_PPTX, ConstObject.haveSaveDemo = true
// ) }
// val list = context.getMediaFile(selectionArgs = selectionArgs) val selectionArgs = arrayOf(
// val documentList = list.map { MIME_TYPE_PPT,
// DocumentBean(it.path, uri = it.uri, type = TYPE_PPT) MIME_TYPE_PPTX,
// } )
// val new = documentList.toMutableList() val list = context.getMediaFile(selectionArgs = selectionArgs)
// val pptDemo = getPPtDemo(context) val documentList = list.map {
// if (File(pptDemo.path).exists()) { DocumentBean(it.path, uri = it.uri, type = TYPE_PPT)
// new.add(0, pptDemo) }
// } val new = documentList.toMutableList()
// return new val pptDemo = getPPtDemo(context)
//} if (File(pptDemo.path).exists()) {
// new.add(0, pptDemo)
// }
//fun recentFilter(recentList: List<String>, documentBean: DocumentBean) { return new
// val findLastTime = recentList.filter { it.contains(documentBean.path) }.map { }
// it.split("_/_")[1].toLong()
// }
// if (findLastTime.isNotEmpty()) { fun recentFilter(recentList: List<String>, documentBean: DocumentBean) {
// val max = findLastTime.max() val findLastTime = recentList.filter { it.contains(documentBean.path) }.map {
// documentBean.lastViewTime = max it.split("_/_")[1].toLong()
// } }
//} if (findLastTime.isNotEmpty()) {
// val max = findLastTime.max()
//fun Context.pdfCheck(pdfDocumentBean: DocumentBean) { documentBean.lastViewTime = max
// pdfDocumentBean.state = this.checkPdfEncryption(pdfDocumentBean.path) }
//} }
//
//fun getDocumentType(mediaBean: MediaBean): String { fun Context.pdfCheck(pdfDocumentBean: DocumentBean) {
// return if (mediaBean.path.endsWith(".pdf")) { pdfDocumentBean.state = this.checkPdfEncryption(pdfDocumentBean.path)
// TYPE_PDF }
// } else if (mediaBean.path.endsWith(".doc") || mediaBean.path.endsWith(".docx")) {
// TYPE_WORD fun getDocumentType(mediaBean: MediaBean): String {
// } else if (mediaBean.path.endsWith(".xls") || mediaBean.path.endsWith(".xlsx")) { return if (mediaBean.path.endsWith(".pdf")) {
// TYPE_EXCEL TYPE_PDF
// } else if (mediaBean.path.endsWith(".ppt") || mediaBean.path.endsWith(".pptx")) { } else if (mediaBean.path.endsWith(".doc") || mediaBean.path.endsWith(".docx")) {
// TYPE_PPT TYPE_WORD
// } else { } else if (mediaBean.path.endsWith(".xls") || mediaBean.path.endsWith(".xlsx")) {
// TYPE_PDF TYPE_EXCEL
// } } else if (mediaBean.path.endsWith(".ppt") || mediaBean.path.endsWith(".pptx")) {
//} TYPE_PPT
// } else {
//fun saveBookmarkChange(addRemove: Boolean, path: String) { TYPE_PDF
// if (addRemove) { }
// SpStringUtils.addSpString(BOOKMARK_KEY, path) }
// } else {
// SpStringUtils.deleteSpString(BOOKMARK_KEY, path) fun saveBookmarkChange(addRemove: Boolean, path: String) {
// } if (addRemove) {
//} SpStringUtils.addSpString(BOOKMARK_KEY, path)
\ No newline at end of file } else {
SpStringUtils.deleteSpString(BOOKMARK_KEY, path)
}
}
\ No newline at end of file
...@@ -19,6 +19,8 @@ class HomeAdapter() : BaseQuickAdapter<HomeUIBean, HomeAdapter.HomeUIBeanViewHol ...@@ -19,6 +19,8 @@ class HomeAdapter() : BaseQuickAdapter<HomeUIBean, HomeAdapter.HomeUIBeanViewHol
inner class HomeUIBeanViewHolder(view: View) : ViewHolder(view) inner class HomeUIBeanViewHolder(view: View) : ViewHolder(view)
var itemClick: ((item: HomeUIBean) -> Unit)? = null
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder: HomeUIBeanViewHolder, position: Int, item: HomeUIBean?) { override fun onBindViewHolder(holder: HomeUIBeanViewHolder, position: Int, item: HomeUIBean?) {
item ?: return item ?: return
...@@ -30,6 +32,9 @@ class HomeAdapter() : BaseQuickAdapter<HomeUIBean, HomeAdapter.HomeUIBeanViewHol ...@@ -30,6 +32,9 @@ class HomeAdapter() : BaseQuickAdapter<HomeUIBean, HomeAdapter.HomeUIBeanViewHol
if (item.fileNumber != -1) { if (item.fileNumber != -1) {
binding.tvFileNumber.text = "${item.fileNumber} files" binding.tvFileNumber.text = "${item.fileNumber} files"
} }
binding.root.setOnClickListener {
itemClick?.invoke(item)
}
} }
UI_TYPE_LIST -> { UI_TYPE_LIST -> {
...@@ -39,6 +44,9 @@ class HomeAdapter() : BaseQuickAdapter<HomeUIBean, HomeAdapter.HomeUIBeanViewHol ...@@ -39,6 +44,9 @@ class HomeAdapter() : BaseQuickAdapter<HomeUIBean, HomeAdapter.HomeUIBeanViewHol
if (item.fileNumber != -1) { if (item.fileNumber != -1) {
binding.tvFileNumber.text = "${item.fileNumber} files" binding.tvFileNumber.text = "${item.fileNumber} files"
} }
binding.root.setOnClickListener {
itemClick?.invoke(item)
}
} }
else -> { else -> {
......
package com.base.pdfoneread.ui.main package com.base.pdfoneread.ui.main
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
...@@ -7,6 +8,8 @@ import android.view.ViewGroup ...@@ -7,6 +8,8 @@ import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import com.base.pdfoneread.R import com.base.pdfoneread.R
import com.base.pdfoneread.bean.DocumentBean.Companion.TYPE_ALL
import com.base.pdfoneread.bean.DocumentBean.Companion.TYPE_PDF
import com.base.pdfoneread.databinding.FragmentHomeBinding import com.base.pdfoneread.databinding.FragmentHomeBinding
import com.base.pdfoneread.bean.HomeUIBean import com.base.pdfoneread.bean.HomeUIBean
import com.base.pdfoneread.bean.HomeUIBean.Companion.KEY_ALL import com.base.pdfoneread.bean.HomeUIBean.Companion.KEY_ALL
...@@ -24,6 +27,7 @@ import com.base.pdfoneread.bean.HomeUIBean.Companion.KEY_WORD ...@@ -24,6 +27,7 @@ import com.base.pdfoneread.bean.HomeUIBean.Companion.KEY_WORD
import com.base.pdfoneread.bean.HomeUIBean.Companion.UI_TYPE_GRID import com.base.pdfoneread.bean.HomeUIBean.Companion.UI_TYPE_GRID
import com.base.pdfoneread.bean.HomeUIBean.Companion.UI_TYPE_LIST import com.base.pdfoneread.bean.HomeUIBean.Companion.UI_TYPE_LIST
import com.base.pdfoneread.bean.HomeUIBean.Companion.UI_TYPE_TITTLE import com.base.pdfoneread.bean.HomeUIBean.Companion.UI_TYPE_TITTLE
import com.base.pdfoneread.ui.document.DocumentActivity
class HomeFragment() : Fragment() { class HomeFragment() : Fragment() {
...@@ -59,6 +63,23 @@ class HomeFragment() : Fragment() { ...@@ -59,6 +63,23 @@ class HomeFragment() : Fragment() {
binding.rv.adapter = adapter binding.rv.adapter = adapter
adapter.submitList(groupList) adapter.submitList(groupList)
adapter.itemClick = { item: HomeUIBean ->
when (item.key) {
KEY_ALL -> {
startActivity(Intent(requireContext(), DocumentActivity::class.java).apply {
putExtra("type", TYPE_ALL)
})
}
KEY_PDF -> {
startActivity(Intent(requireContext(), DocumentActivity::class.java).apply {
putExtra("type", TYPE_PDF)
})
}
}
}
binding.swipeRefreshLayout.setOnRefreshListener { binding.swipeRefreshLayout.setOnRefreshListener {
refreshData() refreshData()
} }
......
...@@ -2,6 +2,7 @@ package com.base.pdfoneread.ui.main ...@@ -2,6 +2,7 @@ package com.base.pdfoneread.ui.main
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.graphics.Color import android.graphics.Color
import androidx.activity.addCallback
import androidx.core.view.updatePadding import androidx.core.view.updatePadding
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.navigation.NavController import androidx.navigation.NavController
...@@ -11,6 +12,7 @@ import com.base.pdfoneread.databinding.ActivityMainBinding ...@@ -11,6 +12,7 @@ import com.base.pdfoneread.databinding.ActivityMainBinding
import com.base.pdfoneread.ui.BaseActivity import com.base.pdfoneread.ui.BaseActivity
import com.base.pdfoneread.bean.HomeUIBean.Companion.UI_TYPE_GRID import com.base.pdfoneread.bean.HomeUIBean.Companion.UI_TYPE_GRID
import com.base.pdfoneread.bean.HomeUIBean.Companion.UI_TYPE_LIST import com.base.pdfoneread.bean.HomeUIBean.Companion.UI_TYPE_LIST
import com.base.pdfoneread.ui.views.MainDialog.showAppExitDialog
import com.base.pdfoneread.utils.BarUtils import com.base.pdfoneread.utils.BarUtils
import com.base.pdfoneread.utils.SpannableUtils.colorSpanner import com.base.pdfoneread.utils.SpannableUtils.colorSpanner
...@@ -30,7 +32,6 @@ class MainActivity : BaseActivity<ActivityMainBinding>() { ...@@ -30,7 +32,6 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
binding.root.updatePadding(top = BarUtils.getStatusBarHeight()) binding.root.updatePadding(top = BarUtils.getStatusBarHeight())
val navHostFragment = val navHostFragment =
supportFragmentManager.findFragmentById(R.id.nav_host_container) as NavHostFragment supportFragmentManager.findFragmentById(R.id.nav_host_container) as NavHostFragment
navController = navHostFragment.navController navController = navHostFragment.navController
...@@ -40,12 +41,13 @@ class MainActivity : BaseActivity<ActivityMainBinding>() { ...@@ -40,12 +41,13 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
override fun initListener() { override fun initListener() {
super.initListener() super.initListener()
onBackPressedDispatcher.addCallback {
showAppExitDialog()
}
binding.llHome.setOnClickListener { binding.llHome.setOnClickListener {
changeHomeUI() changeHomeUI()
} }
binding.llHome.callOnClick() binding.llHome.callOnClick()
binding.llRecent.setOnClickListener { binding.llRecent.setOnClickListener {
changeRecentUI() changeRecentUI()
} }
...@@ -74,7 +76,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() { ...@@ -74,7 +76,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
} }
} }
fun getNavCurrentFragment(): Fragment? { private fun getNavCurrentFragment(): Fragment? {
val navHostFragment: Fragment = binding.navHostContainer.getFragment() val navHostFragment: Fragment = binding.navHostContainer.getFragment()
val currentFragment = navHostFragment.childFragmentManager.primaryNavigationFragment val currentFragment = navHostFragment.childFragmentManager.primaryNavigationFragment
return currentFragment return currentFragment
...@@ -101,7 +103,6 @@ class MainActivity : BaseActivity<ActivityMainBinding>() { ...@@ -101,7 +103,6 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
navController.navigate(R.id.homeFragment) navController.navigate(R.id.homeFragment)
} }
private fun changeRecentUI() { private fun changeRecentUI() {
disSelectTab() disSelectTab()
binding.ivRecent.isSelected = true binding.ivRecent.isSelected = true
......
package com.base.pdfoneread.ui.views package com.base.pdfoneread.ui.views
import android.app.Activity
import android.content.Context import android.content.Context
import android.graphics.Color import android.graphics.Color
import android.text.SpannableString import android.text.SpannableString
...@@ -8,13 +9,14 @@ import android.text.style.ForegroundColorSpan ...@@ -8,13 +9,14 @@ import android.text.style.ForegroundColorSpan
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import com.base.pdfoneread.R import com.base.pdfoneread.R
import com.base.pdfoneread.ads.admob.AdmobNativeUtils
import com.base.pdfoneread.databinding.DialogAppExitBinding
import com.base.pdfoneread.utils.ActivityLauncher import com.base.pdfoneread.utils.ActivityLauncher
import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialog
object MainDialog { object MainDialog {
// fun Context.showStoragePermission( // fun Context.showStoragePermission(
// launcher: ActivityLauncher, // launcher: ActivityLauncher,
// launcherAction: ((flag: Boolean) -> Unit)? = null, // launcherAction: ((flag: Boolean) -> Unit)? = null,
...@@ -59,4 +61,27 @@ object MainDialog { ...@@ -59,4 +61,27 @@ object MainDialog {
// return dialog // return dialog
// //
// } // }
fun Activity.showAppExitDialog() {
val dialog = BottomSheetDialog(this, R.style.BottomSheetDialog)
val binding = DialogAppExitBinding.inflate(LayoutInflater.from(this))
dialog.setContentView(binding.root)
dialog.setCanceledOnTouchOutside(false)
dialog.show()
val parentView = binding.root.parent as View
val behavior = BottomSheetBehavior.from(parentView)
//展开
behavior.state = BottomSheetBehavior.STATE_EXPANDED
AdmobNativeUtils.showNativeAd(this, binding.flAd, R.layout.layout_admob_app_exit)
binding.cardNo.setOnClickListener {
finish()
}
binding.cardYes.setOnClickListener {
dialog.dismiss()
}
}
} }
\ No newline at end of file
package com.base.pdfoneread.utils
import java.text.SimpleDateFormat
import java.util.Locale
object KotlinExt {
fun Number.toFormatSize(count: Int = 1): String {
var suffix = "B"
var fSize = this.toDouble()
if (fSize > 1024) {
suffix = "KB"
fSize /= 1024.0
}
if (fSize > 1024) {
suffix = "MB"
fSize /= 1024.0
}
if (fSize > 1024) {
suffix = "GB"
fSize /= 1024.0
}
return String.format("%.${count}f %s", fSize, suffix)
}
fun Long.toFormatTime(): String {
return SimpleDateFormat("MMM dd,yyyy", Locale.ENGLISH).format(this)
}
fun Long.toFormatTime2(): String {
return SimpleDateFormat("yyyyMMdd_HHmmss", Locale.ENGLISH).format(this)
}
fun Long.toFormatTime3(): String {
return SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH).format(this)
}
fun Long.toFormatTime4(): String {
return SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH).format(this)
}
fun Long.toFormatTime5(): String {
return SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH).format(this)
}
fun Long.toFormatMinute(): String {
return SimpleDateFormat("mm", Locale.ENGLISH).format(this)
}
fun Array<String>.array2String(): String {
val stringBuilder = StringBuilder()
forEach {
stringBuilder.append(it)
}
return stringBuilder.toString()
}
}
\ No newline at end of file
//package com.base.pdfoneread.utils package com.base.pdfoneread.utils
//
//import android.annotation.SuppressLint import android.annotation.SuppressLint
//import android.content.Context import android.content.Context
//import android.database.Cursor import android.database.Cursor
//import android.media.MediaScannerConnection import android.media.MediaScannerConnection
//import android.net.Uri import android.net.Uri
//import android.os.Build import android.os.Build
//import android.os.Environment import android.os.Environment
//import android.provider.DocumentsContract import android.provider.DocumentsContract
//import android.provider.MediaStore import android.provider.MediaStore
//import android.provider.OpenableColumns import android.provider.OpenableColumns
//import kotlinx.coroutines.CoroutineScope import com.base.pdfoneread.bean.ConstObject.MIME_TYPE_APK
//import kotlinx.coroutines.Dispatchers import com.base.pdfoneread.bean.ConstObject.MIME_TYPE_DOC
//import kotlinx.coroutines.async import com.base.pdfoneread.bean.ConstObject.MIME_TYPE_DOCX
//import kotlinx.coroutines.delay import com.base.pdfoneread.bean.ConstObject.MIME_TYPE_PDF
//import kotlinx.coroutines.flow.MutableSharedFlow import com.base.pdfoneread.bean.ConstObject.MIME_TYPE_PPT
//import java.io.File import com.base.pdfoneread.bean.ConstObject.MIME_TYPE_PPTX
// import com.base.pdfoneread.bean.ConstObject.MIME_TYPE_XLS
// import com.base.pdfoneread.bean.ConstObject.MIME_TYPE_XLSX
//private val TAG = "MediaStoreUtils" import com.base.pdfoneread.bean.ConstObject.MIME_TYPE_ZIP
// import com.base.pdfoneread.bean.MediaBean
//private val commonMediaDir = arrayOf( import kotlinx.coroutines.CoroutineScope
// Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).absolutePath, import kotlinx.coroutines.Dispatchers
// Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).absolutePath, import kotlinx.coroutines.async
// Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).absolutePath, import kotlinx.coroutines.delay
// Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES).absolutePath, import kotlinx.coroutines.flow.MutableSharedFlow
//) import java.io.File
//
//fun Context.updateMediaStore(
// filePath: Array<String> = commonMediaDir private val TAG = "MediaStoreUtils"
//) {
// MediaScannerConnection.scanFile( private val commonMediaDir = arrayOf(
// this, filePath, null Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).absolutePath,
// ) { path: String?, uri: Uri? -> } Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).absolutePath,
//} Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).absolutePath,
// Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES).absolutePath,
//fun Context.upDateDemoStore() { )
// val demoFile = File(filesDir, "demo")
// MediaScannerConnection.scanFile( fun Context.updateMediaStore(
// this, arrayOf(demoFile.absolutePath) , null filePath: Array<String> = commonMediaDir
// ) { path: String?, uri: Uri? -> } ) {
//} MediaScannerConnection.scanFile(
// this, filePath, null
////图片视频音频不用这个查 ) { path: String?, uri: Uri? -> }
//fun Context.getMediaFile(selectionArgs: Array<String>? = null): ArrayList<MediaBean> { }
//
// val list = arrayListOf<MediaBean>() fun Context.upDateDemoStore() {
// val demoFile = File(filesDir, "demo")
// val projection = arrayOf( MediaScannerConnection.scanFile(
// MediaStore.Files.FileColumns._ID, this, arrayOf(demoFile.absolutePath), null
// MediaStore.Files.FileColumns.DATA, ) { path: String?, uri: Uri? -> }
//// MediaStore.Files.FileColumns.TITLE, }
// MediaStore.Files.FileColumns.MIME_TYPE,
//// MediaStore.Files.FileColumns.SIZE, //图片视频音频不用这个查
// ) fun Context.getMediaFile(selectionArgs: Array<String>? = null): ArrayList<MediaBean> {
//
// val mimeTypeSelectionArgs = selectionArgs ?: arrayOf( val list = arrayListOf<MediaBean>()
// MIME_TYPE_PDF,
// MIME_TYPE_DOC, val projection = arrayOf(
// MIME_TYPE_DOCX, MediaStore.Files.FileColumns._ID,
// MIME_TYPE_XLS, MediaStore.Files.FileColumns.DATA,
// MIME_TYPE_XLSX, // MediaStore.Files.FileColumns.TITLE,
// MIME_TYPE_PPT, MediaStore.Files.FileColumns.MIME_TYPE,
// MIME_TYPE_PPTX, // MediaStore.Files.FileColumns.SIZE,
// MIME_TYPE_APK )
// )
// val mimeTypeSelectionArgs = selectionArgs ?: arrayOf(
// val mimeTypeSelection = if (mimeTypeSelectionArgs.size == 1) { MIME_TYPE_PDF,
// "${MediaStore.Files.FileColumns.MIME_TYPE} = ?" MIME_TYPE_DOC,
// } else { MIME_TYPE_DOCX,
// "${MediaStore.Files.FileColumns.MIME_TYPE} IN (" + mimeTypeSelectionArgs.joinToString(",") { "?" } + ")" MIME_TYPE_XLS,
// } MIME_TYPE_XLSX,
// MIME_TYPE_PPT,
//// val selection = "$timeSelection AND $mimeTypeSelection" MIME_TYPE_PPTX,
// val selection = mimeTypeSelection MIME_TYPE_APK
// )
// LogEx.logDebug(TAG, "selection=$selection")
// val mimeTypeSelection = if (mimeTypeSelectionArgs.size == 1) {
// var cursor: Cursor? = null "${MediaStore.Files.FileColumns.MIME_TYPE} = ?"
// try { } else {
// // 进行查询,并设置排序方式,按照文件添加时间降序排序 "${MediaStore.Files.FileColumns.MIME_TYPE} IN (" + mimeTypeSelectionArgs.joinToString(",") { "?" } + ")"
// cursor = this.contentResolver.query( }
// MediaStore.Files.getContentUri("external"),
// projection, // val selection = "$timeSelection AND $mimeTypeSelection"
// selection, val selection = mimeTypeSelection
// selectionArgs ?: mimeTypeSelectionArgs,
// MediaStore.Files.FileColumns.DATE_ADDED + " DESC" LogEx.logDebug(TAG, "selection=$selection")
// )
// if (cursor != null) { var cursor: Cursor? = null
// while (cursor.moveToNext()) { try {
// runCatching { // 进行查询,并设置排序方式,按照文件添加时间降序排序
// val id = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns._ID)) cursor = this.contentResolver.query(
// val uri = Uri.withAppendedPath(MediaStore.Files.getContentUri("external"), id.toString()) MediaStore.Files.getContentUri("external"),
// projection,
// val path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DATA)) selection,
//// val title = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.TITLE)) selectionArgs ?: mimeTypeSelectionArgs,
// val mimeType = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.MIME_TYPE)) MediaStore.Files.FileColumns.DATE_ADDED + " DESC"
//// val size = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.SIZE)) )
// if (cursor != null) {
// LogEx.logDebug(TAG, "path=$path uri=$uri mimeType=$mimeType") while (cursor.moveToNext()) {
// list.add( runCatching {
// MediaBean(path = path, uri = uri, mimeType = mimeType) val id = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns._ID))
// ) val uri = Uri.withAppendedPath(MediaStore.Files.getContentUri("external"), id.toString())
// }
// } val path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DATA))
// } // val title = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.TITLE))
// val mimeType = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.MIME_TYPE))
// } catch (e: Exception) { // val size = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.SIZE))
// LogEx.logDebug(TAG, "Exception $e")
// } finally { LogEx.logDebug(TAG, "path=$path uri=$uri mimeType=$mimeType")
// cursor?.close() list.add(
// } MediaBean(path = path, uri = uri, mimeType = mimeType)
// )
// return list }
// }
//} }
//
//@SuppressLint("Range") } catch (e: Exception) {
//fun Context.getMediaPhotoCountSize(): Pair<Int, Long> { LogEx.logDebug(TAG, "Exception $e")
// var count = 0 } finally {
// var totalSize = 0L cursor?.close()
// runCatching { }
// val contentResolver = this.contentResolver
// return list
// // 定义查询的Uri和列
// val uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI }
// val projection = arrayOf(MediaStore.Images.Media._ID, MediaStore.Images.Media.SIZE)
// @SuppressLint("Range")
// // 执行查询 fun Context.getMediaPhotoCountSize(): Pair<Int, Long> {
// val cursor = contentResolver.query(uri, projection, null, null, null) var count = 0
// var totalSize = 0L
// // 检查cursor是否包含数据 runCatching {
// count = cursor?.count ?: 0 val contentResolver = this.contentResolver
// while (cursor?.moveToNext() == true) {
// totalSize += cursor.getInt(cursor.getColumnIndex(MediaStore.Video.Media.SIZE)) // 定义查询的Uri和列
// } val uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
// // 关闭cursor val projection = arrayOf(MediaStore.Images.Media._ID, MediaStore.Images.Media.SIZE)
// cursor?.close()
// } // 执行查询
// val cursor = contentResolver.query(uri, projection, null, null, null)
//
// return Pair(count, totalSize) // 检查cursor是否包含数据
//} count = cursor?.count ?: 0
// while (cursor?.moveToNext() == true) {
//fun Context.getMediaPhoto(): List<MediaBean> { totalSize += cursor.getInt(cursor.getColumnIndex(MediaStore.Video.Media.SIZE))
// }
// val list = arrayListOf<MediaBean>() // 关闭cursor
// val contentResolver = this.contentResolver cursor?.close()
// }
// // 定义查询的Uri和列
// val baseUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
// val projection = arrayOf(MediaStore.Images.Media._ID, MediaStore.Images.Media.DATA) return Pair(count, totalSize)
// }
// // 执行查询
// var cursor: Cursor? = null fun Context.getMediaPhoto(): List<MediaBean> {
//
// try { val list = arrayListOf<MediaBean>()
// cursor = contentResolver.query(baseUri, projection, null, null, null) val contentResolver = this.contentResolver
//
// if (cursor != null) { // 定义查询的Uri和列
// while (cursor.moveToNext()) { val baseUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
// val id = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID)) val projection = arrayOf(MediaStore.Images.Media._ID, MediaStore.Images.Media.DATA)
// val uri = Uri.withAppendedPath(baseUri, id.toString())
// val path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)) // 执行查询
// list.add(MediaBean(path = path, uri = uri, mimeType = "image/*")) var cursor: Cursor? = null
// }
// } try {
// } catch (e: Exception) { cursor = contentResolver.query(baseUri, projection, null, null, null)
//
// } finally { if (cursor != null) {
// cursor?.close() while (cursor.moveToNext()) {
// } val id = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID))
// val uri = Uri.withAppendedPath(baseUri, id.toString())
// return list val path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA))
//} list.add(MediaBean(path = path, uri = uri, mimeType = "image/*"))
// }
//fun Context.getMediaVideo(): List<MediaBean> { }
// } catch (e: Exception) {
// val list = arrayListOf<MediaBean>()
// val contentResolver = this.contentResolver } finally {
// cursor?.close()
// // 定义查询的Uri和列 }
// val baseUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
// val projection = arrayOf(MediaStore.Video.Media._ID, MediaStore.Video.Media.DATA, MediaStore.Video.Media.MIME_TYPE) return list
// }
// // 执行查询
// var cursor: Cursor? = null fun Context.getMediaVideo(): List<MediaBean> {
//
// try { val list = arrayListOf<MediaBean>()
// cursor = contentResolver.query(baseUri, projection, null, null, null) val contentResolver = this.contentResolver
//
// if (cursor != null) { // 定义查询的Uri和列
// while (cursor.moveToNext()) { val baseUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
// val id = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID)) val projection = arrayOf(MediaStore.Video.Media._ID, MediaStore.Video.Media.DATA, MediaStore.Video.Media.MIME_TYPE)
// val uri = Uri.withAppendedPath(baseUri, id.toString())
// LogEx.logDebug(TAG, "getMediaVideo uri=$uri") // 执行查询
// val path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA)) var cursor: Cursor? = null
// val mimeType = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.MIME_TYPE))
// list.add(MediaBean(path = path, uri = uri, mimeType = mimeType)) try {
// } cursor = contentResolver.query(baseUri, projection, null, null, null)
// }
// } catch (e: Exception) { if (cursor != null) {
// while (cursor.moveToNext()) {
// } finally { val id = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID))
// cursor?.close() val uri = Uri.withAppendedPath(baseUri, id.toString())
// } LogEx.logDebug(TAG, "getMediaVideo uri=$uri")
// val path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA))
// return list val mimeType = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.MIME_TYPE))
//} list.add(MediaBean(path = path, uri = uri, mimeType = mimeType))
// }
//fun Context.getMediaAudio(): List<MediaBean> { }
// } catch (e: Exception) {
// val list = arrayListOf<MediaBean>()
// val contentResolver = this.contentResolver } finally {
// cursor?.close()
// // 定义查询的Uri和列 }
// val baseUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
// val projection = arrayOf(MediaStore.Audio.Media._ID, MediaStore.Audio.Media.DATA, MediaStore.Audio.Media.MIME_TYPE) return list
// }
// // 执行查询
// var cursor: Cursor? = null fun Context.getMediaAudio(): List<MediaBean> {
//
// try { val list = arrayListOf<MediaBean>()
// cursor = contentResolver.query(baseUri, projection, null, null, null) val contentResolver = this.contentResolver
//
// if (cursor != null) { // 定义查询的Uri和列
// while (cursor.moveToNext()) { val baseUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
// val id = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID)) val projection = arrayOf(MediaStore.Audio.Media._ID, MediaStore.Audio.Media.DATA, MediaStore.Audio.Media.MIME_TYPE)
// val uri = Uri.withAppendedPath(baseUri, id.toString())
// val path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA)) // 执行查询
// val mimeType = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.MIME_TYPE)) var cursor: Cursor? = null
// list.add(MediaBean(path = path, uri = uri, mimeType = mimeType))
// } try {
// } cursor = contentResolver.query(baseUri, projection, null, null, null)
// } catch (e: Exception) {
// if (cursor != null) {
// } finally { while (cursor.moveToNext()) {
// cursor?.close() val id = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID))
// } val uri = Uri.withAppendedPath(baseUri, id.toString())
// val path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA))
// return list val mimeType = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.MIME_TYPE))
//} list.add(MediaBean(path = path, uri = uri, mimeType = mimeType))
// }
// }
//@SuppressLint("Range") } catch (e: Exception) {
//fun Context.getMediaVideoCountSize(): Pair<Int, Long> {
// } finally {
// var count = 0 cursor?.close()
// var totalSize: Long = 0 }
//
// runCatching { return list
// val contentResolver = this.contentResolver }
//
// // 定义查询的Uri和列
// val uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI @SuppressLint("Range")
// val projection = arrayOf(MediaStore.Video.Media._ID, MediaStore.Video.Media.SIZE) fun Context.getMediaVideoCountSize(): Pair<Int, Long> {
//
// // 执行查询 var count = 0
// val cursor = contentResolver.query(uri, projection, null, null, null) var totalSize: Long = 0
//
// // 检查cursor是否包含数据 runCatching {
// count = cursor?.count ?: 0 val contentResolver = this.contentResolver
// while (cursor?.moveToNext() == true) {
// totalSize += cursor.getInt(cursor.getColumnIndex(MediaStore.Video.Media.SIZE)) // 定义查询的Uri和列
// } val uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
// // 关闭cursor val projection = arrayOf(MediaStore.Video.Media._ID, MediaStore.Video.Media.SIZE)
// cursor?.close()
// } // 执行查询
// return Pair(count, totalSize) val cursor = contentResolver.query(uri, projection, null, null, null)
//}
// // 检查cursor是否包含数据
//@SuppressLint("Range") count = cursor?.count ?: 0
//fun Context.getMediaAudioCountSize(): Pair<Int, Long> { while (cursor?.moveToNext() == true) {
// var count = 0 totalSize += cursor.getInt(cursor.getColumnIndex(MediaStore.Video.Media.SIZE))
// var totalSize: Long = 0 }
// runCatching { // 关闭cursor
// val contentResolver = this.contentResolver cursor?.close()
// }
// // 定义查询的Uri和列 return Pair(count, totalSize)
// val uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI }
// val projection = arrayOf(
// MediaStore.Audio.Media._ID, @SuppressLint("Range")
// MediaStore.Audio.Media.SIZE, fun Context.getMediaAudioCountSize(): Pair<Int, Long> {
// ) var count = 0
// var totalSize: Long = 0
// // 执行查询 runCatching {
// val cursor = contentResolver.query(uri, projection, null, null, null) val contentResolver = this.contentResolver
//
// // 检查cursor是否包含数据 // 定义查询的Uri和列
// count = cursor?.count ?: 0 val uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
// while (cursor?.moveToNext() == true) { val projection = arrayOf(
// totalSize += cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media.SIZE)) MediaStore.Audio.Media._ID,
// } MediaStore.Audio.Media.SIZE,
// )
// // 关闭cursor
// cursor?.close() // 执行查询
// } val cursor = contentResolver.query(uri, projection, null, null, null)
// return Pair(count, totalSize)
//} // 检查cursor是否包含数据
// count = cursor?.count ?: 0
// while (cursor?.moveToNext() == true) {
//fun Context.getMediaDocumentCountSize(): Int { totalSize += cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media.SIZE))
// var count = 0 }
// runCatching {
// val contentResolver = this.contentResolver // 关闭cursor
// cursor?.close()
// val mimeTypeSelectionArgs = arrayOf( }
// MIME_TYPE_PDF, return Pair(count, totalSize)
// MIME_TYPE_DOC, }
// MIME_TYPE_DOCX,
// MIME_TYPE_XLS,
// MIME_TYPE_XLSX, fun Context.getMediaDocumentCountSize(): Int {
// MIME_TYPE_PPT, var count = 0
// MIME_TYPE_PPTX, runCatching {
// ) val contentResolver = this.contentResolver
// val mimeTypeSelection =
// "${MediaStore.Files.FileColumns.MIME_TYPE} IN (" + mimeTypeSelectionArgs.joinToString(",") { "?" } + ")" val mimeTypeSelectionArgs = arrayOf(
// MIME_TYPE_PDF,
// // 定义查询的Uri和列 MIME_TYPE_DOC,
// val uri = MediaStore.Files.getContentUri("external") MIME_TYPE_DOCX,
// val projection = arrayOf(MediaStore.Files.FileColumns._ID) MIME_TYPE_XLS,
// MIME_TYPE_XLSX,
// // 执行查询 MIME_TYPE_PPT,
// val cursor = contentResolver.query(uri, projection, mimeTypeSelection, mimeTypeSelectionArgs, null) MIME_TYPE_PPTX,
// )
// // 检查cursor是否包含数据 val mimeTypeSelection =
// count = cursor?.count ?: 0 "${MediaStore.Files.FileColumns.MIME_TYPE} IN (" + mimeTypeSelectionArgs.joinToString(",") { "?" } + ")"
//
// // 关闭cursor // 定义查询的Uri和列
// cursor?.close() val uri = MediaStore.Files.getContentUri("external")
// } val projection = arrayOf(MediaStore.Files.FileColumns._ID)
// return count
//} // 执行查询
// val cursor = contentResolver.query(uri, projection, mimeTypeSelection, mimeTypeSelectionArgs, null)
//fun Context.getMediaApkCountSize(): Int {
// var count = 0 // 检查cursor是否包含数据
// runCatching { count = cursor?.count ?: 0
// val contentResolver = this.contentResolver
// // 关闭cursor
// val mimeTypeSelectionArgs = arrayOf( cursor?.close()
// MIME_TYPE_APK }
// ) return count
// val mimeTypeSelection = "${MediaStore.Files.FileColumns.MIME_TYPE} = ?" }
//
// // 定义查询的Uri和列 fun Context.getMediaApkCountSize(): Int {
// val uri = MediaStore.Files.getContentUri("external") var count = 0
// val projection = arrayOf(MediaStore.Files.FileColumns._ID) runCatching {
// val contentResolver = this.contentResolver
// // 执行查询
// val cursor = contentResolver.query(uri, projection, mimeTypeSelection, mimeTypeSelectionArgs, null) val mimeTypeSelectionArgs = arrayOf(
// MIME_TYPE_APK
// // 检查cursor是否包含数据 )
// count = cursor?.count ?: 0 val mimeTypeSelection = "${MediaStore.Files.FileColumns.MIME_TYPE} = ?"
//
// // 关闭cursor // 定义查询的Uri和列
// cursor?.close() val uri = MediaStore.Files.getContentUri("external")
// } val projection = arrayOf(MediaStore.Files.FileColumns._ID)
// return count
//} // 执行查询
// val cursor = contentResolver.query(uri, projection, mimeTypeSelection, mimeTypeSelectionArgs, null)
//fun Context.getMediaZipCountSize(): Int {
// var count = 0 // 检查cursor是否包含数据
// runCatching { count = cursor?.count ?: 0
// val contentResolver = this.contentResolver
// // 关闭cursor
// val mimeTypeSelectionArgs = arrayOf( cursor?.close()
// MIME_TYPE_ZIP }
// ) return count
// val mimeTypeSelection = "${MediaStore.Files.FileColumns.MIME_TYPE} = ?" }
//
// // 定义查询的Uri和列 fun Context.getMediaZipCountSize(): Int {
// val uri = MediaStore.Files.getContentUri("external") var count = 0
// val projection = arrayOf(MediaStore.Files.FileColumns._ID) runCatching {
// val contentResolver = this.contentResolver
// // 执行查询
// val cursor = contentResolver.query(uri, projection, mimeTypeSelection, mimeTypeSelectionArgs, null) val mimeTypeSelectionArgs = arrayOf(
// MIME_TYPE_ZIP
// // 检查cursor是否包含数据 )
// count = cursor?.count ?: 0 val mimeTypeSelection = "${MediaStore.Files.FileColumns.MIME_TYPE} = ?"
//
// // 关闭cursor // 定义查询的Uri和列
// cursor?.close() val uri = MediaStore.Files.getContentUri("external")
// } val projection = arrayOf(MediaStore.Files.FileColumns._ID)
// return count
//} // 执行查询
// val cursor = contentResolver.query(uri, projection, mimeTypeSelection, mimeTypeSelectionArgs, null)
//private fun getFileTypeSelection(fileSuffix: String): String {
// return (MediaStore.Files.FileColumns.MEDIA_TYPE + "=" // 检查cursor是否包含数据
// + MediaStore.Files.FileColumns.MEDIA_TYPE_NONE + " AND " count = cursor?.count ?: 0
// + MediaStore.Files.FileColumns.DATA + " LIKE '%" + fileSuffix + "'")
//} // 关闭cursor
// cursor?.close()
// }
//fun CoroutineScope.queryFiles(context: Context, fileSuffix: String, flow: MutableSharedFlow<String>? = null) = return count
// async(Dispatchers.IO) { }
// val selection = getFileTypeSelection(fileSuffix)
// val fileList: MutableList<File> = ArrayList() private fun getFileTypeSelection(fileSuffix: String): String {
// val projection = arrayOf( return (MediaStore.Files.FileColumns.MEDIA_TYPE + "="
// MediaStore.Files.FileColumns._ID, MediaStore.Files.FileColumns.DATA, + MediaStore.Files.FileColumns.MEDIA_TYPE_NONE + " AND "
// ) + MediaStore.Files.FileColumns.DATA + " LIKE '%" + fileSuffix + "'")
// val sortOrder = MediaStore.Files.FileColumns._ID + " DESC" }
// val queryUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL)
// } else { fun CoroutineScope.queryFiles(context: Context, fileSuffix: String, flow: MutableSharedFlow<String>? = null) =
// MediaStore.Files.getContentUri("external") async(Dispatchers.IO) {
// } val selection = getFileTypeSelection(fileSuffix)
// val cursor = context.contentResolver.query(queryUri, projection, selection, null, sortOrder) val fileList: MutableList<File> = ArrayList()
// if (cursor != null) { val projection = arrayOf(
// while (cursor.moveToNext()) { MediaStore.Files.FileColumns._ID, MediaStore.Files.FileColumns.DATA,
// delay(150) )
// val path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DATA)) val sortOrder = MediaStore.Files.FileColumns._ID + " DESC"
// flow?.emit(path) val queryUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// fileList.add(File(path)) MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL)
// } } else {
// cursor.close() MediaStore.Files.getContentUri("external")
// } }
// fileList val cursor = context.contentResolver.query(queryUri, projection, selection, null, sortOrder)
// } if (cursor != null) {
// while (cursor.moveToNext()) {
//fun queryFiles(context: Context, fileSuffix: String): MutableList<File> { delay(150)
// val selection = getFileTypeSelection(fileSuffix) val path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DATA))
// val fileList: MutableList<File> = ArrayList() flow?.emit(path)
// val projection = arrayOf( fileList.add(File(path))
// MediaStore.Files.FileColumns._ID, MediaStore.Files.FileColumns.DATA, }
// ) cursor.close()
// val sortOrder = MediaStore.Files.FileColumns._ID + " DESC" }
// val queryUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { fileList
// MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL) }
// } else {
// MediaStore.Files.getContentUri("external") fun queryFiles(context: Context, fileSuffix: String): MutableList<File> {
// } val selection = getFileTypeSelection(fileSuffix)
// val cursor = context.contentResolver.query(queryUri, projection, selection, null, sortOrder) val fileList: MutableList<File> = ArrayList()
// if (cursor != null) { val projection = arrayOf(
// while (cursor.moveToNext()) { MediaStore.Files.FileColumns._ID, MediaStore.Files.FileColumns.DATA,
// val path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DATA)) )
// fileList.add(File(path)) val sortOrder = MediaStore.Files.FileColumns._ID + " DESC"
// } val queryUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// cursor.close() MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL)
// } } else {
// return fileList MediaStore.Files.getContentUri("external")
//} }
// val cursor = context.contentResolver.query(queryUri, projection, selection, null, sortOrder)
//fun getFileNameFromUri(context: Context, uri: Uri): String { if (cursor != null) {
// var displayName = "" while (cursor.moveToNext()) {
// if (DocumentsContract.isDocumentUri(context, uri)) { val path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DATA))
// val projection = arrayOf(OpenableColumns.DISPLAY_NAME) fileList.add(File(path))
// var cursor: Cursor? = null }
// try { cursor.close()
// cursor = context.contentResolver.query(uri, projection, null, null, null) }
// val column_index = cursor!!.getColumnIndexOrThrow(OpenableColumns.DISPLAY_NAME) return fileList
// if (cursor.moveToFirst()) { }
// displayName = cursor.getString(column_index)
// } fun getFileNameFromUri(context: Context, uri: Uri): String {
// } catch (e: java.lang.Exception) { var displayName = ""
// e.printStackTrace() if (DocumentsContract.isDocumentUri(context, uri)) {
// } finally { val projection = arrayOf(OpenableColumns.DISPLAY_NAME)
// cursor?.close() var cursor: Cursor? = null
// } try {
// } cursor = context.contentResolver.query(uri, projection, null, null, null)
// return displayName val column_index = cursor!!.getColumnIndexOrThrow(OpenableColumns.DISPLAY_NAME)
//} if (cursor.moveToFirst()) {
\ No newline at end of file displayName = cursor.getString(column_index)
}
} catch (e: java.lang.Exception) {
e.printStackTrace()
} finally {
cursor?.close()
}
}
return displayName
}
\ No newline at end of file
//package com.base.pdfoneread.utils package com.base.pdfoneread.utils
//
//import android.content.Context import android.content.Context
//import android.graphics.Bitmap import android.graphics.Bitmap
//import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.BitmapDrawable
//import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
//import android.net.Uri import android.net.Uri
//import com.tom_roush.pdfbox.rendering.RenderDestination import com.base.pdfoneread.utils.UriUtils.readFileToByteArray
//import java.io.File import com.tom_roush.pdfbox.pdmodel.PDDocument
//import java.io.IOException import com.tom_roush.pdfbox.pdmodel.PDPage
// import com.tom_roush.pdfbox.pdmodel.PDPageContentStream
// import com.tom_roush.pdfbox.pdmodel.common.PDRectangle
//object PdfBoxUtils { import com.tom_roush.pdfbox.pdmodel.encryption.AccessPermission
// import com.tom_roush.pdfbox.pdmodel.encryption.StandardProtectionPolicy
// private val TAG = "PdfUtils" import com.tom_roush.pdfbox.pdmodel.graphics.image.PDImageXObject
// import com.tom_roush.pdfbox.rendering.ImageType
// fun getNumberOfPages(context: Context, filePath: String, password: String? = null, uri: String? = null): Int { import com.tom_roush.pdfbox.rendering.PDFRenderer
// val document = context.loadPDDocument(path = filePath, password, uri) import com.tom_roush.pdfbox.rendering.RenderDestination
// return document.numberOfPages import java.io.File
// } import java.io.IOException
//
//
// fun getPdfDrawablePage( object PdfBoxUtils {
// context: Context,
// filePath: String, private val TAG = "PdfUtils"
// password: String? = null,
// uri: String? = null, fun getNumberOfPages(context: Context, filePath: String, password: String? = null, uri: String? = null): Int {
// pageIndex: Int, val document = context.loadPDDocument(path = filePath, password, uri)
// scale: Float = 1f, return document.numberOfPages
// ): Drawable { }
// val document = context.loadPDDocument(filePath, password, uri)
// val renderer = PDFRenderer(document)
// fun getPdfDrawablePage(
// val bitmap: Bitmap = renderer.renderImage(pageIndex, scale, ImageType.RGB, RenderDestination.EXPORT) context: Context,
// filePath: String,
// val drawable = BitmapDrawable(context.resources, bitmap) password: String? = null,
// uri: String? = null,
// return drawable pageIndex: Int,
// } scale: Float = 1f,
// ): Drawable {
// val document = context.loadPDDocument(filePath, password, uri)
// fun Context.checkPdfEncryption(filePath: String = "", uri: String? = null): Int { val renderer = PDFRenderer(document)
// var state = 0
// var pdfDocument: PDDocument? = null val bitmap: Bitmap = renderer.renderImage(pageIndex, scale, ImageType.RGB, RenderDestination.EXPORT)
// try {
// pdfDocument = loadPDDocument(filePath, null, uri) val drawable = BitmapDrawable(context.resources, bitmap)
// pdfDocument.use { document ->
// if (document.isEncrypted) { return drawable
// println("The PDF is encrypted.") }
// val ap = document.getCurrentAccessPermission()
// if (ap.canExtractContent()) {
// println("You are allowed to extract content.") fun Context.checkPdfEncryption(filePath: String = "", uri: String? = null): Int {
// } else { var state = 0
// state = 1 var pdfDocument: PDDocument? = null
// println("You are not allowed to extract content.") try {
// } pdfDocument = loadPDDocument(filePath, null, uri)
// if (ap.canPrint()) { pdfDocument.use { document ->
// println("You are allowed to print the document.") if (document.isEncrypted) {
// } else { println("The PDF is encrypted.")
// println("You are not allowed to print the document.") val ap = document.getCurrentAccessPermission()
// state = 1 if (ap.canExtractContent()) {
// } println("You are allowed to extract content.")
// } else { } else {
// println("The PDF is not encrypted.") state = 1
// state = 0 println("You are not allowed to extract content.")
// } }
// } if (ap.canPrint()) {
// } catch (e: IOException) { println("You are allowed to print the document.")
// e.printStackTrace() } else {
// state = 1 println("You are not allowed to print the document.")
// } finally { state = 1
// pdfDocument?.close() }
// } } else {
// return state println("The PDF is not encrypted.")
// } state = 0
// }
// }
// fun setPassword( } catch (e: IOException) {
// sourceFilePath: String, e.printStackTrace()
// userPassword: String, state = 1
// ownerPassword: String } finally {
// ): Boolean { pdfDocument?.close()
// }
// try { return state
// PDDocument.load(File(sourceFilePath)).use { document -> }
// val ap = AccessPermission()
// ap.setCanPrint(false)
// ap.setCanModify(false) fun setPassword(
// ap.setCanExtractContent(false) sourceFilePath: String,
// ap.setCanExtractForAccessibility(false) userPassword: String,
// ap.setCanFillInForm(false) ownerPassword: String
// val spp = StandardProtectionPolicy(userPassword, ownerPassword, ap) ): Boolean {
// document.protect(spp)
// document.save(File(sourceFilePath)) try {
// LogEx.logDebug(TAG, "setPassword finish") PDDocument.load(File(sourceFilePath)).use { document ->
// } val ap = AccessPermission()
// } catch (e: Exception) { ap.setCanPrint(false)
// LogEx.logDebug(TAG, "setPassword Exception ${e.printStackTrace()}") ap.setCanModify(false)
// e.printStackTrace() ap.setCanExtractContent(false)
// return false ap.setCanExtractForAccessibility(false)
// } ap.setCanFillInForm(false)
// return true val spp = StandardProtectionPolicy(userPassword, ownerPassword, ap)
// } document.protect(spp)
// document.save(File(sourceFilePath))
// fun clearPassword(filePath: String, password: String) { LogEx.logDebug(TAG, "setPassword finish")
// try { }
// PDDocument.load(File(filePath), password).use { document -> } catch (e: Exception) {
// if (document.isEncrypted) { LogEx.logDebug(TAG, "setPassword Exception ${e.printStackTrace()}")
// val ap: AccessPermission = document.getCurrentAccessPermission() e.printStackTrace()
// if (ap.isOwnerPermission) { return false
// // 创建一个新的保护策略,不设置密码 }
// val spp = StandardProtectionPolicy( return true
// "", "", }
// AccessPermission.getOwnerAccessPermission()
// ) fun clearPassword(filePath: String, password: String) {
// document.protect(spp) try {
// } PDDocument.load(File(filePath), password).use { document ->
// } if (document.isEncrypted) {
// // 保存PDF文件到新的位置,没有密码保护 val ap: AccessPermission = document.getCurrentAccessPermission()
// document.save(File(filePath)) if (ap.isOwnerPermission) {
// } // 创建一个新的保护策略,不设置密码
// } catch (e: IOException) { val spp = StandardProtectionPolicy(
// e.printStackTrace() "", "",
// } AccessPermission.getOwnerAccessPermission()
// } )
// document.protect(spp)
// }
// fun Context.checkPwd( }
// filePath: String, // 保存PDF文件到新的位置,没有密码保护
// password: String, document.save(File(filePath))
// uri: String? = null }
// ): Boolean { } catch (e: IOException) {
// try { e.printStackTrace()
// val pdfDocument = loadPDDocument(filePath, password, uri) }
// // 尝试使用提供的密码加载PDF文件 }
// pdfDocument.use { document ->
// // 如果没有抛出异常,说明密码正确
// return true fun Context.checkPwd(
// } filePath: String,
// } catch (e: Exception) { password: String,
// // 加载文件时,如果密码保护策略异常,密码可能错误 uri: String? = null
// println("Incorrect password or restricted permissions.") ): Boolean {
// } catch (e: IOException) { try {
// // 其他I/O异常处理 val pdfDocument = loadPDDocument(filePath, password, uri)
// println("An I/O error occurred: " + e.message) // 尝试使用提供的密码加载PDF文件
// } pdfDocument.use { document ->
// return false // 如果没有抛出异常,说明密码正确
// } return true
// }
// private fun Context.loadPDDocument(path: String, password: String?, uri: String? = null): PDDocument { } catch (e: Exception) {
// return if (uri == null) { // 加载文件时,如果密码保护策略异常,密码可能错误
// if (password == null) { println("Incorrect password or restricted permissions.")
// PDDocument.load(File(path)) } catch (e: IOException) {
// } else { // 其他I/O异常处理
// PDDocument.load(File(path), password) println("An I/O error occurred: " + e.message)
// } }
// } else { return false
// if (password == null) { }
// PDDocument.load(readFileToByteArray(this, Uri.parse(uri)) ?: byteArrayOf())
// private fun Context.loadPDDocument(path: String, password: String?, uri: String? = null): PDDocument {
// } else { return if (uri == null) {
// PDDocument.load(readFileToByteArray(this, Uri.parse(uri)) ?: byteArrayOf(), password) if (password == null) {
// } PDDocument.load(File(path))
// } } else {
// } PDDocument.load(File(path), password)
// }
// } else {
// fun saveNewPdf(imagePath: String, savePath: String) { if (password == null) {
// try { PDDocument.load(readFileToByteArray(this, Uri.parse(uri)) ?: byteArrayOf())
// PDDocument().use { document ->
// // 添加一个页面 } else {
// val page = PDPage(PDRectangle.A4) PDDocument.load(readFileToByteArray(this, Uri.parse(uri)) ?: byteArrayOf(), password)
// document.addPage(page) }
// }
// // 加载图片 }
// val image = PDImageXObject.createFromFile(imagePath, document)
//
// // 计算图片在页面中的位置和尺寸 fun saveNewPdf(imagePath: String, savePath: String) {
// val x = (PDRectangle.A4.width - image.width) / 2 try {
// val y = (PDRectangle.A4.height - image.height) / 2 PDDocument().use { document ->
// PDPageContentStream(document, page).use { contentStream -> // 添加一个页面
// contentStream.drawImage( val page = PDPage(PDRectangle.A4)
// image, document.addPage(page)
// x,
// y, // 加载图片
// image.width.toFloat(), val image = PDImageXObject.createFromFile(imagePath, document)
// image.height.toFloat()
// ) // 计算图片在页面中的位置和尺寸
// } val x = (PDRectangle.A4.width - image.width) / 2
// val y = (PDRectangle.A4.height - image.height) / 2
// // 保存PDF文档 PDPageContentStream(document, page).use { contentStream ->
// document.save(savePath) contentStream.drawImage(
// } image,
// } catch (e: IOException) { x,
// e.printStackTrace() y,
// } image.width.toFloat(),
// } image.height.toFloat()
// )
//} }
\ No newline at end of file
// 保存PDF文档
document.save(savePath)
}
} catch (e: IOException) {
e.printStackTrace()
}
}
}
\ No newline at end of file
package com.base.pdfoneread.utils
object SpStringUtils {
private val TAG = "SpStringUtils"
const val BOOKMARK_KEY = "bookmark_key"
//key=last_view_key value=/data/user/0/com.ttesst.gododo.redause/files/demo/DEMO.pdf_/_1728703007625
const val LAST_VIEW_KEY = "last_view_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) {
LogEx.logDebug(TAG, "key=$key value=$value")
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
package com.base.pdfoneread.utils
import android.content.Context
import android.net.Uri
import com.tom_roush.pdfbox.io.IOUtils
import java.io.InputStream
object UriUtils {
fun readFileToByteArray(context: Context, uri: Uri): ByteArray? {
var inputStream: InputStream? = null
return try {
inputStream = context.contentResolver.openInputStream(uri)
// 读取文件内容到字节数组
IOUtils.toByteArray(inputStream)
} catch (e: java.lang.Exception) {
e.printStackTrace()
null
} finally {
if (inputStream != null) {
try {
inputStream.close()
} catch (e: java.lang.Exception) {
e.printStackTrace()
}
}
}
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#00B5DC" />
<corners android:radius="10dp" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:topLeftRadius="15dp" android:bottomRightRadius="15dp"/>
<solid android:color="#BFE8F3"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#F1F4F9" />
<corners android:radius="15dp" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#F2F2F2" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FF8A00" />
<corners android:radius="10dp" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/white" />
<corners
android:topLeftRadius="15dp"
android:topRightRadius="15dp" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@mipmap/pdf_k_s" android:state_selected="true" />
<item android:drawable="@mipmap/pdf_k1" android:state_selected="false" />
</selector>
\ No newline at end of file
...@@ -7,4 +7,119 @@ ...@@ -7,4 +7,119 @@
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".ui.document.DocumentActivity"> tools:context=".ui.document.DocumentActivity">
<androidx.cardview.widget.CardView
android:id="@+id/card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_top"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
app:layout_constraintTop_toTopOf="parent">
<FrameLayout
android:id="@+id/fl_fanhui"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginVertical="8dp"
android:layout_marginStart="8dp"
android:padding="15dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/pdf_left" />
</FrameLayout>
<TextView
android:id="@+id/tv_tittle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:textColor="@color/black"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@id/fl_fanhui"
app:layout_constraintStart_toEndOf="@id/fl_fanhui"
app:layout_constraintTop_toTopOf="@id/fl_fanhui"
tools:text="All files" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="@id/tv_tittle"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/tv_tittle">
<FrameLayout
android:id="@+id/fl_select"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="15dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/r_pdf_chosen"
tools:ignore="ContentDescription" />
</FrameLayout>
<FrameLayout
android:id="@+id/fl_paixu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="15dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/pdf_transfer"
tools:ignore="ContentDescription" />
</FrameLayout>
<FrameLayout
android:id="@+id/fl_search"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="15dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/icon_search"
tools:ignore="ContentDescription" />
</FrameLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipeRefreshLayout"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/card">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:listitem="@layout/item_document" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
<ImageView <ImageView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:src="@mipmap/h_search" android:src="@mipmap/icon_search"
tools:ignore="ContentDescription" /> tools:ignore="ContentDescription" />
</FrameLayout> </FrameLayout>
...@@ -72,7 +72,6 @@ ...@@ -72,7 +72,6 @@
</androidx.cardview.widget.CardView> </androidx.cardview.widget.CardView>
<androidx.fragment.app.FragmentContainerView <androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_container" android:id="@+id/nav_host_container"
android:name="androidx.navigation.fragment.NavHostFragment" android:name="androidx.navigation.fragment.NavHostFragment"
......
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView 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:layout_width="180dp"
android:layout_height="136dp"
android:layout_margin="5dp"
app:cardCornerRadius="25dp"
app:cardElevation="0dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="23dp"
android:src="@mipmap/jiazai_ad"
tools:ignore="ContentDescription" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="18dp"
android:layout_marginBottom="22dp"
android:includeFontPadding="false"
android:text="@string/preparing_advertisement"
android:textColor="@color/black"
android:textSize="13sp"
tools:ignore="HardcodedText" />
</LinearLayout>
</androidx.cardview.widget.CardView>
\ 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:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_ffffff_tlr15"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/tv_tip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="28dp"
android:text="Are you sure want to exit the app?"
android:textColor="#333333"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
<FrameLayout
android:id="@+id/fl_ad"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="8dp"
android:gravity="center_horizontal"
tools:ignore="Autofill,HardcodedText,LabelFor,TextFields">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:scaleType="fitCenter"
android:src="@mipmap/zhanweitu"
tools:ignore="ContentDescription" />
</FrameLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp"
android:layout_marginBottom="15dp"
android:padding="5dp">
<androidx.cardview.widget.CardView
android:id="@+id/card_no"
android:layout_width="163dp"
android:layout_height="48dp"
app:cardBackgroundColor="#f1f2f6"
app:cardCornerRadius="10dp"
app:cardElevation="0dp">
<TextView
android:id="@+id/tv_no"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:text="@string/exit"
android:textColor="#505050"
android:textSize="18sp"
tools:ignore="HardcodedText" />
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/card_yes"
android:layout_width="163dp"
android:layout_height="48dp"
android:layout_marginStart="14dp"
app:cardBackgroundColor="#00B8DE"
app:cardCornerRadius="10dp"
app:cardElevation="0dp"
tools:ignore="HardcodedText">
<TextView
android:id="@+id/tv_yes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/cancel"
android:textColor="@color/white"
android:textSize="18sp" />
</androidx.cardview.widget.CardView>
</LinearLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
...@@ -100,7 +100,7 @@ ...@@ -100,7 +100,7 @@
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:layout_marginHorizontal="28dp" android:layout_marginHorizontal="28dp"
android:layout_weight="1" android:layout_weight="1"
android:text="@string/evaluage_options" android:text="@string/evaluate_options"
android:textColor="@color/black" android:textColor="@color/black"
android:textSize="14sp" android:textSize="14sp"
android:textStyle="bold" /> android:textStyle="bold" />
......
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/fl_ad"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#F4F5FA">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginVertical="8dp"
android:src="@mipmap/zhanweitu3"
tools:ignore="ContentDescription" />
</FrameLayout>
\ 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:layout_width="match_parent"
android:layout_height="77dp">
<ImageView
android:id="@+id/iv_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="18dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription"
tools:src="@mipmap/rv_pdf" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="11dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/fl_bookmark"
app:layout_constraintStart_toEndOf="@id/iv_icon"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/tv_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:singleLine="true"
android:textColor="#222222"
android:textSize="15sp"
tools:text="Demo.pptx" />
<TextView
android:id="@+id/tv_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:textColor="#59595A"
android:textSize="12sp"
tools:text="01-11-2024 213B" />
</LinearLayout>
<FrameLayout
android:id="@+id/fl_bookmark"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/fl_more"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/r_star_s"
tools:ignore="ContentDescription" />
</FrameLayout>
<FrameLayout
android:id="@+id/fl_more"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:paddingHorizontal="16dp"
android:paddingVertical="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/icon_more"
tools:ignore="ContentDescription" />
</FrameLayout>
<FrameLayout
android:id="@+id/fl_select"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:padding="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/selector_document"
tools:ignore="ContentDescription" />
</FrameLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="42dp"
android:layout_marginEnd="15dp"
android:background="#C4C4C4"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
<com.google.android.gms.ads.nativead.NativeAdView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="@drawable/bg_f1f4f9_15">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:baselineAligned="false"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/bg_bfe8f3_tl15_br15"
android:paddingHorizontal="8dp"
android:paddingVertical="5dp"
android:text="Ad"
android:textColor="#00B5DC"
android:textSize="12sp"
tools:ignore="HardcodedText" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/ad_app_icon"
android:layout_width="42dp"
android:layout_height="42dp"
android:layout_gravity="center_vertical"
android:layout_marginStart="8dp"
tools:ignore="ContentDescription" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginHorizontal="8dp"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/ad_headline"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="2"
android:textColor="#001D29"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:id="@+id/ad_body"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:ellipsize="end"
android:maxLines="2"
android:textColor="@color/black"
android:textSize="12sp" />
</LinearLayout>
</LinearLayout>
<com.google.android.gms.ads.nativead.MediaView
android:id="@+id/ad_media"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_gravity="center_vertical"
android:layout_marginHorizontal="8dp"
android:layout_marginVertical="10dp" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/ad_call_to_action"
android:layout_width="match_parent"
android:layout_height="38dp"
android:layout_marginBottom="10dp"
android:layout_gravity="center_vertical"
android:layout_marginHorizontal="8dp"
android:background="@drawable/bg_00b5dc_10"
android:gravity="center"
android:textAllCaps="false"
android:textColor="@color/white"
android:textSize="15sp"
tools:text="Install" />
</LinearLayout>
</com.google.android.gms.ads.nativead.NativeAdView>
\ No newline at end of file
<com.google.android.gms.ads.nativead.NativeAdView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@drawable/bg_f2f2f2"
android:baselineAligned="false">
<com.google.android.gms.ads.nativead.MediaView
android:id="@+id/ad_media"
android:layout_width="91dp"
android:layout_height="91dp"
android:layout_gravity="center_vertical"
android:layout_marginStart="5dp" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginHorizontal="8dp"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/ad_headline"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="2"
android:textColor="@color/black"
android:textSize="14sp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:background="#FF923E"
android:padding="2dp"
android:text="Ad"
android:textColor="@color/white"
android:textSize="12sp"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/ad_body"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="10dp"
android:ellipsize="end"
android:maxLines="2"
android:textColor="@color/black"
android:textSize="12sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingVertical="5dp">
<ImageView
android:id="@+id/ad_app_icon"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center_vertical"
tools:ignore="ContentDescription" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/ad_call_to_action"
android:layout_width="match_parent"
android:layout_height="26dp"
android:layout_gravity="center_vertical"
android:layout_marginHorizontal="12dp"
android:background="@drawable/bg_ff8a00_10"
android:gravity="center"
android:textColor="@color/white"
android:textSize="15sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</com.google.android.gms.ads.nativead.NativeAdView>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="dp_200">200dp</dimen>
<dimen name="dp_146">146dp</dimen>
</resources>
\ No newline at end of file
<resources> <resources translatable="false">
<string name="app_name">PDF Reader &amp; PDF Editor</string> <string name="app_name">PDF Reader &amp; PDF Editor</string>
<string name="home">Home</string> <string name="home">Home</string>
<string name="recent">Recent</string> <string name="recent">Recent</string>
<string name="settings">Settings</string> <string name="settings">Settings</string>
<string name="file_manager">File Manager</string> <string name="file_manager">File Manager</string>
<string name="set_as_default">Set as Default</string> <string name="set_as_default">Set as Default</string>
<string name="evaluage_options">Evaluage Options</string> <string name="evaluate_options">Evaluate Options</string>
<string name="feedback">Feedback</string> <string name="feedback">Feedback</string>
<string name="privacy_policy">Privacy Policy</string> <string name="privacy_policy">Privacy Policy</string>
<!-- TODO: Remove or change this placeholder text -->
<string name="hello_blank_fragment">Hello blank fragment</string> <string name="hello_blank_fragment">Hello blank fragment</string>
<string name="facebook_app_id">1111111111111</string>
<string name="preparing_advertisement">Preparing advertisement…</string>
<string name="all_files">All files</string>
<string name="pdf_files">PDF files</string>
<string name="word_files">Word files</string>
<string name="excel_files">Excel files</string>
<string name="ppt_files">PPT files</string>
<string name="exit">Exit</string>
</resources> </resources>
\ No newline at end of file
...@@ -27,4 +27,5 @@ dependencyResolutionManagement { ...@@ -27,4 +27,5 @@ dependencyResolutionManagement {
rootProject.name = "Pdf One Read" rootProject.name = "Pdf One Read"
include(":app") include(":app")
include(":library")
\ No newline at end of file include(":pdflibrary")
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