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
This diff is collapsed.
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
...@@ -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
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