init
15
.gitignore
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/caches
|
||||
/.idea/libraries
|
||||
/.idea/modules.xml
|
||||
/.idea/workspace.xml
|
||||
/.idea/navEditor.xml
|
||||
/.idea/assetWizardSettings.xml
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
.externalNativeBuild
|
||||
.cxx
|
||||
local.properties
|
||||
1
app/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/build
|
||||
BIN
app/ArtWallpaper.jks
Normal file
93
app/build.gradle.kts
Normal file
@ -0,0 +1,93 @@
|
||||
import java.util.Date
|
||||
import java.text.SimpleDateFormat
|
||||
|
||||
plugins {
|
||||
alias(libs.plugins.androidApplication)
|
||||
alias(libs.plugins.jetbrainsKotlinAndroid)
|
||||
id("com.google.gms.google-services")
|
||||
id("com.google.firebase.crashlytics")
|
||||
id("applovin-quality-service")
|
||||
}
|
||||
applovin{
|
||||
apiKey = "y87o4e7vb5bbqzuGVTFyOIfZiyBG0Nf0Ksq8S3m2MJOHf_A5BcWGJnKuQqoxwxVvtdQdiTC4O3MPzFwy8rJ9Cc"
|
||||
}
|
||||
val timestamp = SimpleDateFormat("MM_dd_HH_mm").format(Date())
|
||||
android {
|
||||
namespace = "com.cute.girl.hd.pink.img.wallpaper"
|
||||
compileSdk = 34
|
||||
|
||||
defaultConfig {
|
||||
//com.wallart.art.wallpapers.hd
|
||||
applicationId = "com.wallart.art.wallpapers.hd"
|
||||
minSdk = 23
|
||||
targetSdk = 34
|
||||
versionCode = 2
|
||||
versionName = "1.0.1"
|
||||
setProperty("archivesBaseName", "Art Wallpaper_V" + versionName + "(${versionCode})_$timestamp")
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
isMinifyEnabled = true
|
||||
proguardFiles(
|
||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||
"proguard-rules.pro"
|
||||
)
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
||||
kotlinOptions {
|
||||
jvmTarget = "1.8"
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
viewBinding = true
|
||||
buildConfig = true
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
implementation(libs.androidx.core.ktx)
|
||||
implementation(libs.androidx.appcompat)
|
||||
implementation(libs.material)
|
||||
testImplementation(libs.junit)
|
||||
androidTestImplementation(libs.androidx.junit)
|
||||
androidTestImplementation(libs.androidx.espresso.core)
|
||||
//tabLayout
|
||||
implementation("io.github.h07000223:flycoTabLayout:3.0.0")
|
||||
//下拉刷新上拉加载
|
||||
// implementation("io.github.scwang90:refresh-layout-kernel:2.0.5") //核心必须依赖
|
||||
// implementation("io.github.scwang90:refresh-header-classics:2.0.5") //经典刷新头
|
||||
//okhttp
|
||||
implementation("com.squareup.okhttp3:okhttp:4.9.2")
|
||||
implementation("commons-codec:commons-codec:1.11")
|
||||
|
||||
implementation("com.github.bumptech.glide:glide:4.15.1")
|
||||
annotationProcessor("com.github.bumptech.glide:compiler:4.11.0")
|
||||
|
||||
// implementation("com.squareup.retrofit2:retrofit:2.9.0")
|
||||
// implementation("com.squareup.retrofit2:converter-gson:2.9.0")
|
||||
|
||||
implementation("com.squareup.okhttp3:logging-interceptor:4.7.2")
|
||||
implementation("pub.devrel:easypermissions:3.0.0")
|
||||
implementation("com.liulishuo.filedownloader:library:1.7.7")
|
||||
|
||||
implementation ("com.google.code.gson:gson:2.10.1")
|
||||
|
||||
|
||||
|
||||
|
||||
implementation("com.applovin:applovin-sdk:+")
|
||||
implementation("com.applovin.mediation:vungle-adapter:+")
|
||||
implementation("com.applovin.mediation:bytedance-adapter:+")
|
||||
implementation("com.applovin.mediation:mintegral-adapter:+")
|
||||
|
||||
implementation(platform("com.google.firebase:firebase-bom:32.3.1"))
|
||||
implementation("com.google.firebase:firebase-analytics-ktx")
|
||||
implementation ("com.google.firebase:firebase-crashlytics-ktx")
|
||||
}
|
||||
29
app/google-services.json
Normal file
@ -0,0 +1,29 @@
|
||||
{
|
||||
"project_info": {
|
||||
"project_number": "32220085177",
|
||||
"project_id": "art-wallpaper---wallpape-acddd",
|
||||
"storage_bucket": "art-wallpaper---wallpape-acddd.appspot.com"
|
||||
},
|
||||
"client": [
|
||||
{
|
||||
"client_info": {
|
||||
"mobilesdk_app_id": "1:32220085177:android:30846e4694936a9d6f1468",
|
||||
"android_client_info": {
|
||||
"package_name": "com.wallart.art.wallpapers.hd"
|
||||
}
|
||||
},
|
||||
"oauth_client": [],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyCjN36LqkvcimX5OEsnMyYYmWElQRM_-js"
|
||||
}
|
||||
],
|
||||
"services": {
|
||||
"appinvite_service": {
|
||||
"other_platform_oauth_client": []
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"configuration_version": "1"
|
||||
}
|
||||
34
app/proguard-rules.pro
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
|
||||
-keep class com.cute.girl.hd.pink.img.wallpaper.entity.CategoryData { *; }
|
||||
-keep class com.cute.girl.hd.pink.img.wallpaper.entity.Data { *; }
|
||||
|
||||
-dontwarn org.bouncycastle.jsse.BCSSLParameters
|
||||
-dontwarn org.bouncycastle.jsse.BCSSLSocket
|
||||
-dontwarn org.bouncycastle.jsse.provider.BouncyCastleJsseProvider
|
||||
-dontwarn org.conscrypt.Conscrypt$Version
|
||||
-dontwarn org.conscrypt.Conscrypt
|
||||
-dontwarn org.conscrypt.ConscryptHostnameVerifier
|
||||
-dontwarn org.openjsse.javax.net.ssl.SSLParameters
|
||||
-dontwarn org.openjsse.javax.net.ssl.SSLSocket
|
||||
-dontwarn org.openjsse.net.ssl.OpenJSSE
|
||||
@ -0,0 +1,24 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ExampleInstrumentedTest {
|
||||
@Test
|
||||
fun useAppContext() {
|
||||
// Context of the app under test.
|
||||
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
assertEquals("com.cute.girl.hd.pink.img.wallpaper", appContext.packageName)
|
||||
}
|
||||
}
|
||||
75
app/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,75 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.SET_WALLPAPER" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
|
||||
<application
|
||||
android:name=".MyApp"
|
||||
android:allowBackup="true"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
android:fullBackupContent="@xml/backup_rules"
|
||||
android:icon="@mipmap/logo"
|
||||
android:label="@string/app_name"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
android:roundIcon="@mipmap/logo"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.PinkWallpaper"
|
||||
android:usesCleartextTraffic="true"
|
||||
tools:targetApi="31">
|
||||
|
||||
<activity
|
||||
android:name=".page.StartAbility"
|
||||
android:exported="true"
|
||||
android:screenOrientation="fullSensor"
|
||||
tools:ignore="DiscouragedApi">
|
||||
<!-- <intent-filter>-->
|
||||
<!-- <action android:name="android.intent.action.MAIN" />-->
|
||||
|
||||
<!-- <category android:name="android.intent.category.LAUNCHER" />-->
|
||||
<!-- </intent-filter>-->
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".page.CategoryAbility"
|
||||
android:exported="false"
|
||||
android:screenOrientation="fullSensor"
|
||||
tools:ignore="DiscouragedApi" />
|
||||
|
||||
<activity
|
||||
android:name=".page.CategoryPreviewAbility"
|
||||
android:exported="false"
|
||||
android:screenOrientation="fullSensor"
|
||||
tools:ignore="DiscouragedApi" />
|
||||
|
||||
<activity
|
||||
android:name=".page.MainAbility"
|
||||
android:exported="true"
|
||||
android:screenOrientation="fullSensor"
|
||||
tools:ignore="DiscouragedApi" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".page.PreviewAbility"
|
||||
android:exported="false"
|
||||
android:screenOrientation="fullSensor"
|
||||
tools:ignore="DiscouragedApi" />
|
||||
|
||||
<activity
|
||||
android:name=".page.PrivacyAbility"
|
||||
android:exported="false"
|
||||
android:screenOrientation="fullSensor"
|
||||
tools:ignore="DiscouragedApi" />
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
2251
app/src/main/assets/test_new.json
Normal file
126
app/src/main/java/com/cute/girl/hd/pink/img/wallpaper/MyApp.kt
Normal file
@ -0,0 +1,126 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper
|
||||
|
||||
import android.app.Application
|
||||
import android.content.Intent
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
||||
import com.applovin.sdk.AppLovinMediationProvider
|
||||
import com.applovin.sdk.AppLovinSdk
|
||||
import com.applovin.sdk.AppLovinSdkInitializationConfiguration
|
||||
import com.cute.girl.hd.pink.img.wallpaper.entity.CategoryData
|
||||
import com.cute.girl.hd.pink.img.wallpaper.entity.Data
|
||||
import com.liulishuo.filedownloader.FileDownloader
|
||||
import org.json.JSONArray
|
||||
import java.io.BufferedReader
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.io.FileOutputStream
|
||||
import java.io.InputStream
|
||||
import java.io.InputStreamReader
|
||||
import java.io.StringWriter
|
||||
import java.nio.charset.StandardCharsets
|
||||
|
||||
class MyApp : Application() {
|
||||
companion object {
|
||||
lateinit var app: MyApp
|
||||
lateinit var myData: List<CategoryData>
|
||||
|
||||
const val MAX_SDK = "3cUMfTcsZKzlJevxK4IkNysgDAeQA4B5w332p3g8B9ZAgC54WQNZLVxuxnCx4sCHA5StLJnDTAFa68mFTi8rd8"
|
||||
const val AD_INIT_ACTION = "on_success_action"
|
||||
var initSDK = false
|
||||
}
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
app = this
|
||||
initSDK()
|
||||
FileDownloader.setup(this)
|
||||
readJson()
|
||||
}
|
||||
|
||||
private fun readJson() {
|
||||
val openFd = assets.open("test_new.json")
|
||||
val pathDe = cacheDir.path + "/res.json"
|
||||
if (File(pathDe).exists()) {
|
||||
myData = fileToData(pathDe)
|
||||
return
|
||||
}
|
||||
if (writeFile(openFd, pathDe)) {
|
||||
myData = fileToData(pathDe)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private fun fileToData(path: String): List<CategoryData> {
|
||||
val jsonStr = getJsonStr(path)
|
||||
var data = mutableListOf<CategoryData>()
|
||||
val array = JSONArray(jsonStr)
|
||||
for (i in 0 until array.length()) {
|
||||
val any = array.getJSONObject(i)
|
||||
val title = any.getString("name")
|
||||
val jsonArray = any.getJSONArray("list")
|
||||
var data1 = mutableListOf<Data>()
|
||||
for (k in 0 until jsonArray.length()) {
|
||||
val jsonObject = jsonArray.getJSONObject(k)
|
||||
val source = jsonObject.getString("sourceUrl")
|
||||
val preview = jsonObject.getString("preUrl")
|
||||
data1.add(Data(preview, source))
|
||||
}
|
||||
data.add(CategoryData(title, data1))
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
|
||||
fun writeFile(input: InputStream, filePath: String): Boolean {
|
||||
|
||||
val byte = ByteArray(4096)
|
||||
val output = ByteArrayOutputStream()
|
||||
var l: Int
|
||||
while (input.read(byte).also { l = it } != -1) {
|
||||
output.write(byte, 0, l)
|
||||
}
|
||||
val fileDe = File(filePath)
|
||||
if (!fileDe.exists()) {
|
||||
fileDe.createNewFile()
|
||||
}
|
||||
val fileOutputStream = FileOutputStream(filePath)
|
||||
|
||||
fileOutputStream.write(output.toByteArray())
|
||||
output.close()
|
||||
fileOutputStream.close()
|
||||
return true
|
||||
|
||||
}
|
||||
|
||||
fun getJsonStr(resPath: String): String {
|
||||
val stringWriter = StringWriter()
|
||||
val input = FileInputStream(resPath)
|
||||
val charArray = CharArray(input.available())
|
||||
var l = 0;
|
||||
val bufReader = BufferedReader(InputStreamReader(input, StandardCharsets.UTF_8))
|
||||
while (bufReader.read(charArray).also {
|
||||
l = it
|
||||
} != -1) {
|
||||
stringWriter.write(charArray, 0, l)
|
||||
}
|
||||
return stringWriter.toString()
|
||||
|
||||
}
|
||||
|
||||
|
||||
private fun initSDK() {
|
||||
val initConfig =
|
||||
AppLovinSdkInitializationConfiguration.builder(MAX_SDK, this)
|
||||
.setMediationProvider(AppLovinMediationProvider.MAX)
|
||||
.build()
|
||||
AppLovinSdk.getInstance(this).initialize(initConfig) {
|
||||
initSDK = true
|
||||
LocalBroadcastManager.getInstance(this).sendBroadcast(Intent(AD_INIT_ACTION))
|
||||
}
|
||||
AppLovinSdk.getInstance(this).settings.setVerboseLogging(true)
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,98 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper.adapter
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.DataSource
|
||||
import com.bumptech.glide.load.engine.GlideException
|
||||
import com.bumptech.glide.request.target.Target
|
||||
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
|
||||
import com.bumptech.glide.request.RequestListener
|
||||
import com.cute.girl.hd.pink.img.wallpaper.databinding.ItemCategoryBinding
|
||||
import com.cute.girl.hd.pink.img.wallpaper.entity.CategoryData
|
||||
import com.cute.girl.hd.pink.img.wallpaper.entity.GCategory
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.GlobalExt.hide
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.GlobalExt.show
|
||||
|
||||
class CategoryAdapter(private val ctx: Context, private val list: List<CategoryData>) :
|
||||
RecyclerView.Adapter<CategoryAdapter.VH>() {
|
||||
|
||||
private var mListener: OnItemClickListener? = null
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
|
||||
return VH(ItemCategoryBinding.inflate(LayoutInflater.from(ctx), parent, false))
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: VH, position: Int) {
|
||||
if (list.isEmpty()) {
|
||||
return
|
||||
}
|
||||
if (position >= list.size) {
|
||||
return
|
||||
}
|
||||
val bean = list[position]
|
||||
holder.getRoot()?.let {
|
||||
it.setOnClickListener { mListener?.onItemClick(bean) }
|
||||
}
|
||||
|
||||
holder.mItemBinding?.tvTitle?.text = bean.title
|
||||
holder.mItemBinding?.ivPlaceholder?.show()
|
||||
holder.mItemBinding?.ivWallpaper?.let {
|
||||
Glide.with(ctx)
|
||||
.load(bean.data[0].previewURl)
|
||||
.transition(DrawableTransitionOptions.withCrossFade())
|
||||
.listener(object : RequestListener<Drawable> {
|
||||
override fun onLoadFailed(
|
||||
e: GlideException?,
|
||||
model: Any?,
|
||||
target: Target<Drawable>?,
|
||||
isFirstResource: Boolean
|
||||
): Boolean {
|
||||
holder.mItemBinding?.ivPlaceholder?.show()
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onResourceReady(
|
||||
resource: Drawable?,
|
||||
model: Any?,
|
||||
target: Target<Drawable>?,
|
||||
dataSource: DataSource?,
|
||||
isFirstResource: Boolean
|
||||
): Boolean {
|
||||
holder.mItemBinding?.ivPlaceholder?.hide()
|
||||
return false
|
||||
}
|
||||
})
|
||||
.into(it)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return list.size
|
||||
}
|
||||
|
||||
fun setOnItemClickListener(listener: OnItemClickListener) {
|
||||
mListener = listener
|
||||
}
|
||||
|
||||
interface OnItemClickListener {
|
||||
fun onItemClick(categoryData: CategoryData)
|
||||
}
|
||||
|
||||
class VH(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
|
||||
var mItemBinding: ItemCategoryBinding? = null
|
||||
|
||||
constructor(binding: ItemCategoryBinding) : this(binding.root) {
|
||||
this.mItemBinding = binding
|
||||
}
|
||||
|
||||
fun getRoot(): View? {
|
||||
return mItemBinding?.root
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,108 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper.adapter
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.DataSource
|
||||
import com.bumptech.glide.load.engine.GlideException
|
||||
import com.bumptech.glide.request.target.Target
|
||||
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
|
||||
import com.bumptech.glide.request.RequestListener
|
||||
import com.cute.girl.hd.pink.img.wallpaper.databinding.ItemImageBinding
|
||||
import com.cute.girl.hd.pink.img.wallpaper.entity.Data
|
||||
import com.cute.girl.hd.pink.img.wallpaper.entity.GCategoryDetail
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.DeviceUtil
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.GlobalExt.dp2PxInt
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.GlobalExt.hide
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.GlobalExt.show
|
||||
|
||||
class CategoryDetailAdapter(private val ctx: Context, private val list: List<Data>) :
|
||||
RecyclerView.Adapter<CategoryDetailAdapter.VH>() {
|
||||
|
||||
private var mListener: OnItemClickListener? = null
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
|
||||
return VH(ItemImageBinding.inflate(LayoutInflater.from(ctx), parent, false))
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: VH, position: Int) {
|
||||
if (list.isEmpty()) {
|
||||
return
|
||||
}
|
||||
if (position >= list.size) {
|
||||
return
|
||||
}
|
||||
val bean = list[position]
|
||||
holder.getRoot()?.let {
|
||||
it.setOnClickListener { mListener?.onItemClick(bean) }
|
||||
val params = it.layoutParams
|
||||
val itemWidth = (DeviceUtil.getScreenWidth(ctx) - 8.dp2PxInt()) / 3f
|
||||
params.width = itemWidth.toInt()
|
||||
val itemHeight =
|
||||
((itemWidth * DeviceUtil.getScreenHeight(ctx) / DeviceUtil.getScreenWidth(
|
||||
ctx
|
||||
) * 1f)).toInt()
|
||||
params.height = itemHeight
|
||||
it.layoutParams = params
|
||||
}
|
||||
|
||||
holder.mItemBinding?.ivPlaceholder?.show()
|
||||
holder.mItemBinding?.ivWallpaper?.let {
|
||||
Glide.with(ctx)
|
||||
.load(bean.previewURl)
|
||||
.transition(DrawableTransitionOptions.withCrossFade())
|
||||
.listener(object : RequestListener<Drawable> {
|
||||
override fun onLoadFailed(
|
||||
e: GlideException?,
|
||||
model: Any?,
|
||||
target: Target<Drawable>?,
|
||||
isFirstResource: Boolean
|
||||
): Boolean {
|
||||
holder.mItemBinding?.ivPlaceholder?.show()
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onResourceReady(
|
||||
resource: Drawable?,
|
||||
model: Any?,
|
||||
target: Target<Drawable>?,
|
||||
dataSource: DataSource?,
|
||||
isFirstResource: Boolean
|
||||
): Boolean {
|
||||
holder.mItemBinding?.ivPlaceholder?.hide()
|
||||
return false
|
||||
}
|
||||
})
|
||||
.into(it)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return list.size
|
||||
}
|
||||
|
||||
fun setOnItemClickListener(listener: OnItemClickListener) {
|
||||
mListener = listener
|
||||
}
|
||||
|
||||
interface OnItemClickListener {
|
||||
fun onItemClick(pos: Data)
|
||||
}
|
||||
|
||||
class VH(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
|
||||
var mItemBinding: ItemImageBinding? = null
|
||||
|
||||
constructor(binding: ItemImageBinding) : this(binding.root) {
|
||||
this.mItemBinding = binding
|
||||
}
|
||||
|
||||
fun getRoot(): View? {
|
||||
return mItemBinding?.root
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,107 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper.adapter
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.DataSource
|
||||
import com.bumptech.glide.load.engine.GlideException
|
||||
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
|
||||
import com.bumptech.glide.request.RequestListener
|
||||
import com.bumptech.glide.request.target.Target
|
||||
import com.cute.girl.hd.pink.img.wallpaper.databinding.ItemPreviewBinding
|
||||
import com.cute.girl.hd.pink.img.wallpaper.entity.Data
|
||||
import com.cute.girl.hd.pink.img.wallpaper.entity.GCategoryDetail
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.DownloadUtil
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.GlobalExt.hide
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.GlobalExt.show
|
||||
|
||||
class CategoryPagerAdapter(private val ctx: Context, private val list: MutableList<Data>) :
|
||||
RecyclerView.Adapter<CategoryPagerAdapter.VH>() {
|
||||
|
||||
private var mListener: OnItemClickListener? = null
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
|
||||
return VH(ItemPreviewBinding.inflate(LayoutInflater.from(ctx), parent, false))
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: VH, position: Int) {
|
||||
if (list.isEmpty()) {
|
||||
return
|
||||
}
|
||||
if (position >= list.size) {
|
||||
return
|
||||
}
|
||||
val bean = list[position]
|
||||
holder.mItemBinding?.ivPlaceholder?.show()
|
||||
|
||||
|
||||
val url = if (DownloadUtil.isExist(bean.sourceURl, bean.getTag())) {
|
||||
DownloadUtil.getFilePath(bean.sourceURl, bean.getTag())
|
||||
} else {
|
||||
bean.previewURl
|
||||
}
|
||||
|
||||
// val url =bean.previewURl
|
||||
|
||||
holder.mItemBinding?.ivWallpaper?.let {
|
||||
Glide.with(ctx)
|
||||
.load(url)
|
||||
.transition(DrawableTransitionOptions.withCrossFade())
|
||||
.listener(object : RequestListener<Drawable> {
|
||||
override fun onLoadFailed(
|
||||
e: GlideException?,
|
||||
model: Any?,
|
||||
target: Target<Drawable>?,
|
||||
isFirstResource: Boolean
|
||||
): Boolean {
|
||||
holder.mItemBinding?.ivPlaceholder?.show()
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onResourceReady(
|
||||
resource: Drawable?,
|
||||
model: Any?,
|
||||
target: Target<Drawable>?,
|
||||
dataSource: DataSource?,
|
||||
isFirstResource: Boolean
|
||||
): Boolean {
|
||||
holder.mItemBinding?.ivPlaceholder?.hide()
|
||||
return false
|
||||
}
|
||||
})
|
||||
.into(it)
|
||||
}
|
||||
holder.getRoot()?.let {
|
||||
it.setOnClickListener { mListener?.onItemClick(position) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return list.size
|
||||
}
|
||||
|
||||
fun setOnItemClickListener(listener: OnItemClickListener) {
|
||||
mListener = listener
|
||||
}
|
||||
|
||||
interface OnItemClickListener {
|
||||
fun onItemClick(pos: Int)
|
||||
}
|
||||
|
||||
class VH(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
|
||||
var mItemBinding: ItemPreviewBinding? = null
|
||||
|
||||
constructor(binding: ItemPreviewBinding) : this(binding.root) {
|
||||
this.mItemBinding = binding
|
||||
}
|
||||
|
||||
fun getRoot(): View? {
|
||||
return mItemBinding?.root
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,114 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper.adapter
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.DataSource
|
||||
import com.bumptech.glide.load.engine.GlideException
|
||||
import com.bumptech.glide.request.target.Target
|
||||
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
|
||||
import com.bumptech.glide.request.RequestListener
|
||||
import com.cute.girl.hd.pink.img.wallpaper.databinding.ItemImageBinding
|
||||
import com.cute.girl.hd.pink.img.wallpaper.entity.CategoryData
|
||||
import com.cute.girl.hd.pink.img.wallpaper.entity.Data
|
||||
import com.cute.girl.hd.pink.img.wallpaper.entity.GImage
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.DeviceUtil
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.GlobalExt.dp2PxInt
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.GlobalExt.hide
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.GlobalExt.show
|
||||
|
||||
class ImageGridAdapter(private val ctx: Context, private var list: List<Data>) :
|
||||
RecyclerView.Adapter<ImageGridAdapter.VH>() {
|
||||
|
||||
private var mListener: OnItemClickListener? = null
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
|
||||
return VH(ItemImageBinding.inflate(LayoutInflater.from(ctx), parent, false))
|
||||
}
|
||||
|
||||
fun refresh(data: List<Data>) {
|
||||
list = data
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: VH, position: Int) {
|
||||
if (list.isEmpty()) {
|
||||
return
|
||||
}
|
||||
if (position >= list.size) {
|
||||
return
|
||||
}
|
||||
val bean = list[position]
|
||||
holder.getRoot()?.let {
|
||||
it.setOnClickListener { mListener?.onItemClick(bean) }
|
||||
val params = it.layoutParams
|
||||
val itemWidth = (DeviceUtil.getScreenWidth(ctx) - 8.dp2PxInt()) / 3f
|
||||
params.width = itemWidth.toInt()
|
||||
val itemHeight =
|
||||
((itemWidth * DeviceUtil.getScreenHeight(ctx) / DeviceUtil.getScreenWidth(
|
||||
ctx
|
||||
) * 1f)).toInt()
|
||||
params.height = itemHeight
|
||||
it.layoutParams = params
|
||||
}
|
||||
|
||||
holder.mItemBinding?.ivPlaceholder?.show()
|
||||
holder.mItemBinding?.ivWallpaper?.let {
|
||||
Glide.with(ctx)
|
||||
.load(bean.previewURl)
|
||||
.transition(DrawableTransitionOptions.withCrossFade())
|
||||
.listener(object : RequestListener<Drawable> {
|
||||
override fun onLoadFailed(
|
||||
e: GlideException?,
|
||||
model: Any?,
|
||||
target: Target<Drawable>?,
|
||||
isFirstResource: Boolean
|
||||
): Boolean {
|
||||
holder.mItemBinding?.ivPlaceholder?.show()
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onResourceReady(
|
||||
resource: Drawable?,
|
||||
model: Any?,
|
||||
target: Target<Drawable>?,
|
||||
dataSource: DataSource?,
|
||||
isFirstResource: Boolean
|
||||
): Boolean {
|
||||
holder.mItemBinding?.ivPlaceholder?.hide()
|
||||
return false
|
||||
}
|
||||
})
|
||||
.into(it)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return list.size
|
||||
}
|
||||
|
||||
fun setOnItemClickListener(listener: OnItemClickListener) {
|
||||
mListener = listener
|
||||
}
|
||||
|
||||
interface OnItemClickListener {
|
||||
fun onItemClick(posData: Data)
|
||||
}
|
||||
|
||||
class VH(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
|
||||
var mItemBinding: ItemImageBinding? = null
|
||||
|
||||
constructor(binding: ItemImageBinding) : this(binding.root) {
|
||||
this.mItemBinding = binding
|
||||
}
|
||||
|
||||
fun getRoot(): View? {
|
||||
return mItemBinding?.root
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,106 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper.adapter
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.DataSource
|
||||
import com.bumptech.glide.load.engine.GlideException
|
||||
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
|
||||
import com.bumptech.glide.request.RequestListener
|
||||
import com.bumptech.glide.request.target.Target
|
||||
import com.cute.girl.hd.pink.img.wallpaper.databinding.ItemPreviewBinding
|
||||
import com.cute.girl.hd.pink.img.wallpaper.entity.Data
|
||||
import com.cute.girl.hd.pink.img.wallpaper.entity.GImage
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.DownloadUtil
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.GlobalExt.hide
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.GlobalExt.show
|
||||
|
||||
class ImagePagerAdapter(private val ctx: Context, private val list: MutableList<Data>) :
|
||||
RecyclerView.Adapter<ImagePagerAdapter.VH>() {
|
||||
|
||||
private var mListener: OnItemClickListener? = null
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
|
||||
return VH(ItemPreviewBinding.inflate(LayoutInflater.from(ctx), parent, false))
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: VH, position: Int) {
|
||||
if (list.isEmpty()) {
|
||||
return
|
||||
}
|
||||
if (position >= list.size) {
|
||||
return
|
||||
}
|
||||
val bean = list[position]
|
||||
holder.mItemBinding?.ivPlaceholder?.show()
|
||||
|
||||
|
||||
val url = if (DownloadUtil.isExist(bean.sourceURl, bean.getTag())) {
|
||||
DownloadUtil.getFilePath(bean.sourceURl, bean.getTag())
|
||||
} else {
|
||||
bean.previewURl
|
||||
}
|
||||
|
||||
|
||||
holder.mItemBinding?.ivWallpaper?.let {
|
||||
Glide.with(ctx)
|
||||
.load(url)
|
||||
.transition(DrawableTransitionOptions.withCrossFade())
|
||||
.listener(object : RequestListener<Drawable> {
|
||||
override fun onLoadFailed(
|
||||
e: GlideException?,
|
||||
model: Any?,
|
||||
target: Target<Drawable>?,
|
||||
isFirstResource: Boolean
|
||||
): Boolean {
|
||||
holder.mItemBinding?.ivPlaceholder?.show()
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onResourceReady(
|
||||
resource: Drawable?,
|
||||
model: Any?,
|
||||
target: Target<Drawable>?,
|
||||
dataSource: DataSource?,
|
||||
isFirstResource: Boolean
|
||||
): Boolean {
|
||||
holder.mItemBinding?.ivPlaceholder?.hide()
|
||||
return false
|
||||
}
|
||||
})
|
||||
.into(it)
|
||||
}
|
||||
holder.getRoot()?.let {
|
||||
it.setOnClickListener { mListener?.onItemClick(position) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return list.size
|
||||
}
|
||||
|
||||
fun setOnItemClickListener(listener: OnItemClickListener) {
|
||||
mListener = listener
|
||||
}
|
||||
|
||||
interface OnItemClickListener {
|
||||
fun onItemClick(pos: Int)
|
||||
}
|
||||
|
||||
class VH(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
|
||||
var mItemBinding: ItemPreviewBinding? = null
|
||||
|
||||
constructor(binding: ItemPreviewBinding) : this(binding.root) {
|
||||
this.mItemBinding = binding
|
||||
}
|
||||
|
||||
fun getRoot(): View? {
|
||||
return mItemBinding?.root
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper.entity
|
||||
|
||||
import java.io.Serializable
|
||||
|
||||
class CategoryData(var title:String,var data:List<Data>):Serializable
|
||||
@ -0,0 +1,7 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper.entity
|
||||
|
||||
import java.io.Serializable
|
||||
|
||||
class CategoryPreviewBean : Serializable {
|
||||
var list: MutableList<GCategoryDetail> = mutableListOf()
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper.entity
|
||||
|
||||
import android.util.Log
|
||||
import java.io.Serializable
|
||||
|
||||
class Data(var previewURl: String, var sourceURl: String) : Serializable {
|
||||
|
||||
fun getTag(): String {
|
||||
val lastIndex1 = sourceURl.lastIndexOf("/")
|
||||
|
||||
val lastIndex2 = sourceURl.lastIndexOf(".")
|
||||
|
||||
val substring = sourceURl.substring(lastIndex1, lastIndex2)
|
||||
Log.d("-----------","----------$substring")
|
||||
|
||||
return substring
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper.entity
|
||||
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.des.DES
|
||||
import java.io.Serializable
|
||||
|
||||
class GCategory(
|
||||
val cid: String,
|
||||
val category_name: String,
|
||||
val category_image: String,
|
||||
val order_no: String
|
||||
) : Serializable {
|
||||
fun getPreviewUrl(): String {
|
||||
return "http://${DES.decrypt("J ¯ñ\u001C\u008C\u0084Ûü\u0005nÖS\u000F\u0098\u001DD ¾;>ÅEðÃIH\u0096ð{Rl·4Æß&ÿ¦Vú#\u001EÅ/\u0082`;")}$category_image"
|
||||
}
|
||||
|
||||
fun getTag(): String {
|
||||
return "$cid"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper.entity
|
||||
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.des.DES
|
||||
import java.io.Serializable
|
||||
|
||||
class GCategoryDetail(
|
||||
val cid: String,
|
||||
val images: String,
|
||||
val is_premium: String,
|
||||
val cat_name: String
|
||||
) : Serializable {
|
||||
fun getPreviewUrl(): String {
|
||||
return "http://${DES.decrypt("J ¯ñ\u001C\u008C\u0084Ûü\u0005nÖS\u000F\u0098\u001DD ¾;>ÅEðÃIH\u0096ð{Rlþ\u0002£\"uJE\u001EPÒÀÁËz`\u0018")}$images"
|
||||
}
|
||||
|
||||
fun getSUrl(): String {
|
||||
return "http://${DES.decrypt("J ¯ñ\u001C\u008C\u0084Ûü\u0005nÖS\u000F\u0098\u001DD ¾;>ÅEðÃIH\u0096ð{Rl\u0089i²aÙc\u001CA")}$images"
|
||||
}
|
||||
|
||||
fun getTag(): String {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,45 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper.entity
|
||||
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.des.DES
|
||||
import java.io.Serializable
|
||||
|
||||
/**
|
||||
*
|
||||
* "cid": "30",
|
||||
* "category_name": "puppies",
|
||||
* "category_image": "3873-2017-11-18.jpg",
|
||||
* "order_no": "20",
|
||||
* "id": "7322",
|
||||
* "cat_id": "30",
|
||||
* "color_id": "0",
|
||||
* "image_date": null,
|
||||
* "image": "681581_1691845871.jpeg",
|
||||
* "is_popular": "0",
|
||||
* "is_featured": "0",
|
||||
* "is_premium": "0"
|
||||
*/
|
||||
class GImage(
|
||||
val cid: String,
|
||||
val category_name: String,
|
||||
val category_image: String,
|
||||
val order_no: String,
|
||||
val id: String,
|
||||
val cat_id: String,
|
||||
val color_id: String,
|
||||
val image: String,
|
||||
val is_popular: String,
|
||||
val is_featured: String,
|
||||
val is_premium: String,
|
||||
) : Serializable {
|
||||
fun getPreviewUrl(): String {
|
||||
return "http://${DES.decrypt("J ¯ñ\u001C\u008C\u0084Ûü\u0005nÖS\u000F\u0098\u001DD ¾;>ÅEðÃIH\u0096ð{Rlþ\u0002£\"uJE\u001EPÒÀÁËz`\u0018")}$image"
|
||||
}
|
||||
|
||||
// fun sourceURl: String {
|
||||
// return "http://${DES.decrypt("J ¯ñ\u001C\u008C\u0084Ûü\u0005nÖS\u000F\u0098\u001DD ¾;>ÅEðÃIH\u0096ð{Rl\u0089i²aÙc\u001CA")}$image"
|
||||
// }
|
||||
|
||||
fun getTag(): String {
|
||||
return "$id"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper.entity
|
||||
|
||||
object IntentConstants {
|
||||
const val KEY_STRING = "key_string"
|
||||
const val KEY_STRING2 = "key_string2"
|
||||
const val KEY_BOOLEAN = "key_boolean"
|
||||
const val KEY_LIST = "key_list"
|
||||
const val KEY_POS = "key_pos"
|
||||
const val KEY_FROM = "key_from"
|
||||
const val KEY_BEAN = "key_bean"
|
||||
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper.entity
|
||||
|
||||
import java.io.Serializable
|
||||
|
||||
class PreviewBean : Serializable {
|
||||
var list: MutableList<GImage> = mutableListOf()
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper.mymax;
|
||||
|
||||
import com.applovin.mediation.MaxAd;
|
||||
|
||||
public interface MaxCallBack {
|
||||
void onShowFail(MaxAd ad);
|
||||
void onAdHidden( );
|
||||
}
|
||||
@ -0,0 +1,92 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper.mymax;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.applovin.mediation.MaxAd;
|
||||
import com.applovin.mediation.MaxAdListener;
|
||||
import com.applovin.mediation.MaxError;
|
||||
import com.applovin.mediation.ads.MaxInterstitialAd;
|
||||
import com.cute.girl.hd.pink.img.wallpaper.MyApp;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class MaxUtils {
|
||||
|
||||
private static final String one_AD = "3580a29f73375939";
|
||||
private static final String two_Ad = "255b8d8daf7ef9d9";
|
||||
private static final String three_ad = "fe989ddbb91ecdf6";
|
||||
|
||||
private static ArrayList<MaxInterstitialAd> adArrayList;
|
||||
|
||||
public static MaxInterstitialAd onCache(List<MaxInterstitialAd> list) {
|
||||
Collections.shuffle(list);
|
||||
for (MaxInterstitialAd ad : list) {
|
||||
if (ad.isReady()) {
|
||||
return ad;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public static List<MaxInterstitialAd> getAllAd() {
|
||||
if(adArrayList == null){
|
||||
Log.d("-----","--------getAllAd");
|
||||
adArrayList = new ArrayList<>();
|
||||
MaxInterstitialAd AdT = new MaxInterstitialAd(two_Ad, MyApp.app);
|
||||
MaxInterstitialAd AdOne = new MaxInterstitialAd(one_AD, MyApp.app);
|
||||
MaxInterstitialAd AdThree = new MaxInterstitialAd(three_ad, MyApp.app);
|
||||
AdOne.loadAd();
|
||||
AdT.loadAd();
|
||||
AdThree.loadAd();
|
||||
adArrayList.add(AdOne);
|
||||
adArrayList.add(AdT);
|
||||
adArrayList.add(AdThree);
|
||||
}
|
||||
for(MaxInterstitialAd ad:adArrayList){
|
||||
if(!ad.isReady()){
|
||||
Log.d("-----","--------loadAd="+ad.getAdUnitId());
|
||||
ad.loadAd();
|
||||
}
|
||||
}
|
||||
return adArrayList;
|
||||
}
|
||||
public static void setMAXCAllBack(MaxInterstitialAd ad, MaxCallBack maxCallBack) {
|
||||
ad.setListener(new MaxAdListener() {
|
||||
@Override
|
||||
public void onAdLoaded(@NonNull MaxAd maxAd) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAdDisplayed(@NonNull MaxAd maxAd) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAdHidden(@NonNull MaxAd maxAd) {
|
||||
maxCallBack.onAdHidden();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAdClicked(@NonNull MaxAd maxAd) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAdLoadFailed(@NonNull String s, @NonNull MaxError maxError) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAdDisplayFailed(@NonNull MaxAd maxAd, @NonNull MaxError maxError) {
|
||||
maxCallBack.onShowFail(maxAd);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,216 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper.page
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import com.cute.girl.hd.pink.img.wallpaper.adapter.CategoryDetailAdapter
|
||||
import com.cute.girl.hd.pink.img.wallpaper.databinding.AbilityCategoryBinding
|
||||
import com.cute.girl.hd.pink.img.wallpaper.entity.CategoryData
|
||||
import com.cute.girl.hd.pink.img.wallpaper.entity.CategoryPreviewBean
|
||||
import com.cute.girl.hd.pink.img.wallpaper.entity.Data
|
||||
import com.cute.girl.hd.pink.img.wallpaper.entity.GCategoryDetail
|
||||
import com.cute.girl.hd.pink.img.wallpaper.entity.IntentConstants
|
||||
//import com.cute.girl.hd.pink.img.wallpaper.net.base.BaseListener
|
||||
//import com.cute.girl.hd.pink.img.wallpaper.net.base.ServiceImage
|
||||
//import com.cute.girl.hd.pink.img.wallpaper.net.response.ResponseCategoryDetail
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.GlobalExt.hide
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.GlobalExt.onMain
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.GlobalExt.show
|
||||
import com.cute.girl.hd.pink.img.wallpaper.view.CustomItemDecoration
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
class CategoryAbility : AppCompatActivity() {
|
||||
private lateinit var binding: AbilityCategoryBinding
|
||||
private var mList: MutableList<GCategoryDetail> = mutableListOf()
|
||||
private var mAdapter: CategoryDetailAdapter? = null
|
||||
// private var mService: ServiceImage<ResponseCategoryDetail>? = null
|
||||
private var isLoading = AtomicBoolean(false)
|
||||
private var mPage = 1
|
||||
private lateinit var mCid :CategoryData
|
||||
private var mCName = ""
|
||||
|
||||
companion object {
|
||||
fun start(context: Context, categoryData: CategoryData) {
|
||||
val intent = Intent(context, CategoryAbility::class.java)
|
||||
intent.putExtra(IntentConstants.KEY_STRING, categoryData)
|
||||
// intent.putExtra(IntentConstants.KEY_STRING2, cName)
|
||||
context.startActivity(intent)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = AbilityCategoryBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
setupViews()
|
||||
binding.ivBack.setOnClickListener {
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupViews() {
|
||||
if (intent.hasExtra(IntentConstants.KEY_STRING)) {
|
||||
if (intent.getSerializableExtra(IntentConstants.KEY_STRING) != null) {
|
||||
mCid = intent.getSerializableExtra(IntentConstants.KEY_STRING) as CategoryData
|
||||
}
|
||||
}
|
||||
// if (intent.hasExtra(IntentConstants.KEY_STRING2)) {
|
||||
// if (intent.getStringExtra(IntentConstants.KEY_STRING2) != null) {
|
||||
// mCName = intent.getStringExtra(IntentConstants.KEY_STRING2)!!
|
||||
// }
|
||||
// }
|
||||
// if (TextUtils.isEmpty(mCid)) {
|
||||
// finish()
|
||||
// return
|
||||
// }
|
||||
|
||||
binding.tvTitle.text = mCid.title
|
||||
mAdapter = CategoryDetailAdapter(this, mCid.data)
|
||||
mAdapter?.setOnItemClickListener(object :
|
||||
CategoryDetailAdapter.OnItemClickListener {
|
||||
override fun onItemClick(pos: Data) {
|
||||
|
||||
toPreview(pos)
|
||||
}
|
||||
})
|
||||
binding.rv.layoutManager = GridLayoutManager(this, 3)
|
||||
binding.rv.addItemDecoration(
|
||||
CustomItemDecoration(1, 2)
|
||||
)
|
||||
binding.rv.adapter = mAdapter!!
|
||||
|
||||
// //下拉刷新
|
||||
// binding.refreshLayout.setOnRefreshListener {
|
||||
// if (isLoading.get()) {
|
||||
// return@setOnRefreshListener
|
||||
// }
|
||||
// refresh()
|
||||
// }
|
||||
//
|
||||
// //上拉加载
|
||||
// binding.refreshLayout.setOnLoadMoreListener {
|
||||
// if (isLoading.get()) {
|
||||
// return@setOnLoadMoreListener
|
||||
// }
|
||||
//// loadMore()
|
||||
// }
|
||||
|
||||
refresh()
|
||||
}
|
||||
private fun refresh(){
|
||||
|
||||
}
|
||||
// private fun refresh() {
|
||||
// if (mService == null) {
|
||||
// mService = ServiceImage()
|
||||
// }
|
||||
// if (isLoading.get()) {
|
||||
// return
|
||||
// }
|
||||
// isLoading.set(true)
|
||||
// mPage = 1
|
||||
// mService?.let { service ->
|
||||
// val call = service.mApi.getImageByCId(mCid, 1)
|
||||
// service.callEnqueue(call, object : BaseListener<ResponseCategoryDetail> {
|
||||
// override fun onResponse(t: ResponseCategoryDetail?) {
|
||||
// if (t != null) {
|
||||
// if (t.MaterialWallpaper != null && t.MaterialWallpaper.isNotEmpty()) {
|
||||
// mList.clear()
|
||||
// mList.addAll(t.MaterialWallpaper.toMutableList())
|
||||
// isLoading.set(false)
|
||||
// onMain {
|
||||
// mAdapter?.notifyDataSetChanged()
|
||||
// updateView()
|
||||
// }
|
||||
// } else {
|
||||
// onMain {
|
||||
// updateView()
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// onMain {
|
||||
// updateView()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// override fun onFail(e: String?) {
|
||||
// isLoading.set(false)
|
||||
// onMain {
|
||||
// mAdapter?.notifyDataSetChanged()
|
||||
// updateView()
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
|
||||
private fun loadMore() {
|
||||
// if (mService == null) {
|
||||
// mService = ServiceImage()
|
||||
// }
|
||||
// if (isLoading.get()) {
|
||||
// return
|
||||
// }
|
||||
// isLoading.set(true)
|
||||
// val newPage = mPage + 1
|
||||
// mService?.let { service ->
|
||||
// val call = service.mApi.getImageByCId(mCid, 1)
|
||||
// service.callEnqueue(call, object : BaseListener<ResponseCategoryDetail> {
|
||||
// override fun onResponse(t: ResponseCategoryDetail?) {
|
||||
// if (t != null) {
|
||||
// if (t.MaterialWallpaper != null && t.MaterialWallpaper.isNotEmpty()) {
|
||||
// mList.addAll(t.MaterialWallpaper.toMutableList())
|
||||
// isLoading.set(false)
|
||||
// mPage = newPage
|
||||
// onMain {
|
||||
// mAdapter?.notifyDataSetChanged()
|
||||
// updateView()
|
||||
// }
|
||||
// } else {
|
||||
// onMain {
|
||||
// updateView()
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// onMain {
|
||||
// updateView()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// override fun onFail(e: String?) {
|
||||
// isLoading.set(false)
|
||||
// onMain {
|
||||
// mAdapter?.notifyDataSetChanged()
|
||||
// updateView()
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
}
|
||||
|
||||
fun updateView() {
|
||||
// binding.refreshLayout.finishRefresh()
|
||||
// binding.refreshLayout.finishLoadMore()
|
||||
if (mList.isNotEmpty()) {
|
||||
binding.tvEmpty.hide()
|
||||
} else {
|
||||
binding.tvEmpty.show()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun toPreview(pos: Data) {
|
||||
// if (pos < 0 || pos >= mList.size) {
|
||||
// return
|
||||
// }
|
||||
val listBean = CategoryPreviewBean()
|
||||
listBean.list = mList
|
||||
CategoryPreviewAbility.start(this, pos)
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,136 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper.page
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import com.cute.girl.hd.pink.img.wallpaper.MyApp
|
||||
import com.cute.girl.hd.pink.img.wallpaper.adapter.CategoryAdapter
|
||||
import com.cute.girl.hd.pink.img.wallpaper.databinding.PageRecentBinding
|
||||
import com.cute.girl.hd.pink.img.wallpaper.entity.CategoryData
|
||||
import com.cute.girl.hd.pink.img.wallpaper.entity.GCategory
|
||||
//import com.cute.girl.hd.pink.img.wallpaper.net.base.BaseListener
|
||||
//import com.cute.girl.hd.pink.img.wallpaper.net.base.ServiceImage
|
||||
//import com.cute.girl.hd.pink.img.wallpaper.net.response.ResponseCategory
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.GlobalExt.hide
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.GlobalExt.onMain
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.GlobalExt.show
|
||||
import com.cute.girl.hd.pink.img.wallpaper.view.CustomItemDecoration
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
class CategoryPage : Fragment() {
|
||||
private lateinit var binding: PageRecentBinding
|
||||
private var mList: MutableList<GCategory> = mutableListOf()
|
||||
private var mAdapter: CategoryAdapter? = null
|
||||
// private var mService: ServiceImage<ResponseCategory>? = null
|
||||
private var isLoading = AtomicBoolean(false)
|
||||
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
binding = PageRecentBinding.inflate(layoutInflater)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
setupViews()
|
||||
}
|
||||
|
||||
private fun setupViews() {
|
||||
|
||||
val subList = MyApp.myData.subList(3, MyApp.myData.size)
|
||||
|
||||
mAdapter = CategoryAdapter(requireActivity(), subList)
|
||||
mAdapter?.setOnItemClickListener(object :
|
||||
CategoryAdapter.OnItemClickListener {
|
||||
override fun onItemClick(pos: CategoryData) {
|
||||
toDetail(pos)
|
||||
}
|
||||
})
|
||||
binding.rv.layoutManager = GridLayoutManager(requireContext(), 2)
|
||||
binding.rv.addItemDecoration(
|
||||
CustomItemDecoration(1, 2)
|
||||
)
|
||||
binding.rv.adapter = mAdapter!!
|
||||
|
||||
//下拉刷新
|
||||
// binding.refreshLayout.setOnRefreshListener {
|
||||
// if (isLoading.get()) {
|
||||
// return@setOnRefreshListener
|
||||
// }
|
||||
// refresh()
|
||||
// }
|
||||
|
||||
refresh()
|
||||
}
|
||||
|
||||
private fun refresh() {
|
||||
// if (mService == null) {
|
||||
// mService = ServiceImage()
|
||||
// }
|
||||
// if (isLoading.get()) {
|
||||
// return
|
||||
// }
|
||||
// isLoading.set(true)
|
||||
// mService?.let { service ->
|
||||
// val call = service.mApi.getCategory()
|
||||
// service.callEnqueue(call, object : BaseListener<ResponseCategory> {
|
||||
// override fun onResponse(t: ResponseCategory?) {
|
||||
// if (t != null) {
|
||||
// if (t.MaterialWallpaper != null && t.MaterialWallpaper.isNotEmpty()) {
|
||||
// mList.clear()
|
||||
// mList.addAll(t.MaterialWallpaper.toMutableList())
|
||||
// isLoading.set(false)
|
||||
// onMain {
|
||||
// mAdapter?.notifyDataSetChanged()
|
||||
// updateView()
|
||||
// }
|
||||
// } else {
|
||||
// onMain {
|
||||
// updateView()
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// onMain {
|
||||
// updateView()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// override fun onFail(e: String?) {
|
||||
// isLoading.set(false)
|
||||
// onMain {
|
||||
// mAdapter?.notifyDataSetChanged()
|
||||
// updateView()
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
}
|
||||
|
||||
fun updateView() {
|
||||
// binding.refreshLayout.finishRefresh()
|
||||
// binding.refreshLayout.finishLoadMore()
|
||||
if (mList.isNotEmpty()) {
|
||||
binding.tvEmpty.hide()
|
||||
} else {
|
||||
binding.tvEmpty.show()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun toDetail(pos: CategoryData) {
|
||||
// if (pos < 0 || pos >= mList.size) {
|
||||
// return
|
||||
// }
|
||||
if (activity != null) {
|
||||
CategoryAbility.start(requireActivity(), pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,346 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper.page
|
||||
|
||||
import android.app.WallpaperManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.view.WindowManager
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
import com.cute.girl.hd.pink.img.wallpaper.R
|
||||
import com.cute.girl.hd.pink.img.wallpaper.adapter.CategoryPagerAdapter
|
||||
import com.cute.girl.hd.pink.img.wallpaper.databinding.AbilityPreviewBinding
|
||||
import com.cute.girl.hd.pink.img.wallpaper.entity.CategoryPreviewBean
|
||||
import com.cute.girl.hd.pink.img.wallpaper.entity.Data
|
||||
import com.cute.girl.hd.pink.img.wallpaper.entity.GCategoryDetail
|
||||
import com.cute.girl.hd.pink.img.wallpaper.entity.IntentConstants
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.DownloadUtil
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.GlobalExt.getString
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.GlobalExt.hide
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.GlobalExt.onMain
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.GlobalExt.show
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.MediaUtil
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.PermissionUtil
|
||||
import com.cute.girl.hd.pink.img.wallpaper.view.SetAsDialog
|
||||
import com.liulishuo.filedownloader.BaseDownloadTask
|
||||
import com.liulishuo.filedownloader.FileDownloadListener
|
||||
import com.liulishuo.filedownloader.FileDownloader
|
||||
import kotlinx.coroutines.launch
|
||||
import pub.devrel.easypermissions.EasyPermissions
|
||||
import java.io.File
|
||||
|
||||
class CategoryPreviewAbility : AppCompatActivity(), EasyPermissions.PermissionCallbacks {
|
||||
private lateinit var binding: AbilityPreviewBinding
|
||||
private var mList: MutableList<Data> = mutableListOf()
|
||||
private var mCurPos: Int = 0
|
||||
private var mImagePagerAdapter: CategoryPagerAdapter? = null
|
||||
private var mSetAsDialog: SetAsDialog? = null
|
||||
private var mAction = 0//0设置壁纸 1下载壁纸
|
||||
|
||||
companion object {
|
||||
fun start(context: Context,bean: Data) {
|
||||
val intent = Intent(context, CategoryPreviewAbility::class.java)
|
||||
intent.putExtra(IntentConstants.KEY_LIST, bean)
|
||||
// intent.putExtra(IntentConstants.KEY_POS, pos)
|
||||
context.startActivity(intent)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = AbilityPreviewBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
setupViews()
|
||||
}
|
||||
|
||||
private fun setupViews() {
|
||||
//隐藏状态栏和底部导航栏
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
|
||||
window.decorView.systemUiVisibility =
|
||||
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_FULLSCREEN
|
||||
|
||||
initData()
|
||||
setUpView()
|
||||
}
|
||||
|
||||
private fun initData() {
|
||||
var listBean: Data? = null
|
||||
if (intent.hasExtra(IntentConstants.KEY_LIST)) {
|
||||
listBean = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
intent.getSerializableExtra(IntentConstants.KEY_LIST, Data::class.java)
|
||||
} else {
|
||||
intent.getSerializableExtra(IntentConstants.KEY_LIST) as Data?
|
||||
}
|
||||
}
|
||||
if (listBean == null) {
|
||||
finish()
|
||||
return
|
||||
}
|
||||
mList.clear()
|
||||
mList.add(listBean)
|
||||
|
||||
if (mList.size == 0) {
|
||||
finish()
|
||||
return
|
||||
}
|
||||
|
||||
mCurPos = intent.getIntExtra(IntentConstants.KEY_POS, 0)
|
||||
|
||||
if (mCurPos < 0 || mCurPos >= mList.size) {
|
||||
finish()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
private fun setUpView() {
|
||||
mImagePagerAdapter = CategoryPagerAdapter(this, mList)
|
||||
mImagePagerAdapter?.setOnItemClickListener(object :
|
||||
CategoryPagerAdapter.OnItemClickListener {
|
||||
override fun onItemClick(pos: Int) {
|
||||
|
||||
}
|
||||
})
|
||||
binding.viewPager.adapter = mImagePagerAdapter!!
|
||||
binding.viewPager.setCurrentItem(mCurPos, false)
|
||||
binding.viewPager.registerOnPageChangeCallback(object :
|
||||
ViewPager2.OnPageChangeCallback() {
|
||||
override fun onPageSelected(position: Int) {
|
||||
mCurPos = position
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
binding.ivBack.setOnClickListener {
|
||||
onBackPressed()
|
||||
}
|
||||
|
||||
binding.tvSet.setOnClickListener {
|
||||
mAction = 0
|
||||
if (isExist()) {
|
||||
set4KWallpaper()
|
||||
} else {
|
||||
startDownload()
|
||||
}
|
||||
}
|
||||
|
||||
binding.tvDownload.setOnClickListener {
|
||||
doSave()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
mSetAsDialog?.dismiss()
|
||||
}
|
||||
|
||||
private fun isExist(): Boolean {
|
||||
return DownloadUtil.isExist(
|
||||
mList[mCurPos].sourceURl,
|
||||
mList[mCurPos].getTag()
|
||||
)
|
||||
}
|
||||
|
||||
private fun set4KWallpaper() {
|
||||
val image = mList[mCurPos]
|
||||
val path =
|
||||
DownloadUtil.getFilePath(
|
||||
image.sourceURl,
|
||||
image.getTag()
|
||||
)
|
||||
val file = File(path)
|
||||
if (!file.exists()) {
|
||||
return
|
||||
}
|
||||
val wallpaperManager = WallpaperManager.getInstance(this)
|
||||
if (mSetAsDialog == null) {
|
||||
mSetAsDialog = SetAsDialog(this) {
|
||||
onClickHomeScreen = {
|
||||
lifecycleScope.launch {
|
||||
wallpaperManager.setStream(
|
||||
file.inputStream(),
|
||||
null,
|
||||
true,
|
||||
WallpaperManager.FLAG_SYSTEM
|
||||
)
|
||||
onMain {
|
||||
Toast.makeText(
|
||||
this@CategoryPreviewAbility,
|
||||
R.string.set_success.getString(),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onClickLockScreen = {
|
||||
lifecycleScope.launch {
|
||||
wallpaperManager.setStream(
|
||||
file.inputStream(),
|
||||
null,
|
||||
true,
|
||||
WallpaperManager.FLAG_LOCK
|
||||
)
|
||||
onMain {
|
||||
Toast.makeText(
|
||||
this@CategoryPreviewAbility,
|
||||
R.string.set_success.getString(),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onClickBoth = {
|
||||
lifecycleScope.launch {
|
||||
wallpaperManager.setStream(file.inputStream())//FLAG_SYSTEM | FLAG_LOCK)
|
||||
onMain {
|
||||
Toast.makeText(
|
||||
this@CategoryPreviewAbility,
|
||||
R.string.set_success.getString(),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mSetAsDialog?.show()
|
||||
}
|
||||
|
||||
private fun doSave() {
|
||||
if (!PermissionUtil.hasStoragePermission(this)) {
|
||||
PermissionUtil.requestStoragePermission(this)
|
||||
return
|
||||
}
|
||||
clickSave()
|
||||
}
|
||||
|
||||
private fun clickSave() {
|
||||
mAction = 1
|
||||
if (isExist()) {
|
||||
saveWallpaper()
|
||||
} else {
|
||||
startDownload()
|
||||
}
|
||||
}
|
||||
|
||||
private fun startDownload() {
|
||||
if (isFinishing) {
|
||||
return
|
||||
}
|
||||
binding.flDownload.show()
|
||||
FileDownloader.getImpl().create(mList[mCurPos].sourceURl)
|
||||
.setPath(DownloadUtil.getFilePath(mList[mCurPos].sourceURl, mList[mCurPos].getTag()))
|
||||
.setCallbackProgressTimes(300)
|
||||
.setMinIntervalUpdateSpeed(400)
|
||||
.setListener(object : FileDownloadListener() {
|
||||
override fun pending(task: BaseDownloadTask?, soFarBytes: Int, totalBytes: Int) {
|
||||
|
||||
}
|
||||
|
||||
override fun progress(task: BaseDownloadTask?, soFarBytes: Int, totalBytes: Int) {
|
||||
if (!isFinishing) {
|
||||
binding.pbb.show()
|
||||
}
|
||||
}
|
||||
|
||||
override fun completed(task: BaseDownloadTask?) {
|
||||
if (!isFinishing) {
|
||||
binding.flDownload.hide()
|
||||
mImagePagerAdapter?.notifyItemChanged(mCurPos)
|
||||
if (mAction == 0) {
|
||||
set4KWallpaper()
|
||||
} else {
|
||||
saveWallpaper()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun paused(task: BaseDownloadTask?, soFarBytes: Int, totalBytes: Int) {
|
||||
if (!isFinishing) {
|
||||
binding.flDownload.hide()
|
||||
Toast.makeText(
|
||||
this@CategoryPreviewAbility,
|
||||
R.string.download_failed,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
|
||||
override fun error(task: BaseDownloadTask?, e: Throwable?) {
|
||||
if (!isFinishing) {
|
||||
binding.flDownload.hide()
|
||||
Toast.makeText(
|
||||
this@CategoryPreviewAbility,
|
||||
R.string.download_failed,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
|
||||
override fun warn(task: BaseDownloadTask?) {
|
||||
if (!isFinishing) {
|
||||
binding.flDownload.hide()
|
||||
Toast.makeText(
|
||||
this@CategoryPreviewAbility,
|
||||
R.string.download_failed,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
|
||||
}).start()
|
||||
}
|
||||
|
||||
private fun saveWallpaper() {
|
||||
val image = mList[mCurPos]
|
||||
val path =
|
||||
DownloadUtil.getFilePath(
|
||||
image.sourceURl,
|
||||
image.getTag()
|
||||
)
|
||||
val saved = MediaUtil.saveImageToSystemAlbum(path, this@CategoryPreviewAbility)
|
||||
if (!isFinishing) {
|
||||
if (saved) {
|
||||
Toast.makeText(
|
||||
this@CategoryPreviewAbility,
|
||||
R.string.saved_to_album,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
} else {
|
||||
Toast.makeText(
|
||||
this@CategoryPreviewAbility,
|
||||
R.string.save_failed,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
override fun onRequestPermissionsResult(
|
||||
requestCode: Int,
|
||||
permissions: Array<out String>,
|
||||
grantResults: IntArray
|
||||
) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this)
|
||||
}
|
||||
|
||||
override fun onPermissionsGranted(requestCode: Int, perms: MutableList<String>) {
|
||||
if (requestCode == PermissionUtil.REQUEST_CODE_PERMISSION_STORAGE) {
|
||||
doSave()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPermissionsDenied(requestCode: Int, perms: MutableList<String>) {
|
||||
if (requestCode == PermissionUtil.REQUEST_CODE_PERMISSION_STORAGE) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,102 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper.page
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import com.cute.girl.hd.pink.img.wallpaper.MyApp
|
||||
import com.cute.girl.hd.pink.img.wallpaper.adapter.ImageGridAdapter
|
||||
import com.cute.girl.hd.pink.img.wallpaper.databinding.PageRecentBinding
|
||||
import com.cute.girl.hd.pink.img.wallpaper.entity.Data
|
||||
import com.cute.girl.hd.pink.img.wallpaper.entity.GImage
|
||||
import com.cute.girl.hd.pink.img.wallpaper.entity.PreviewBean
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.GlobalExt.hide
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.GlobalExt.show
|
||||
import com.cute.girl.hd.pink.img.wallpaper.view.CustomItemDecoration
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
class FeaturePage : Fragment() {
|
||||
private lateinit var binding: PageRecentBinding
|
||||
private var mList: MutableList<GImage> = mutableListOf()
|
||||
private var mAdapter: ImageGridAdapter? = null
|
||||
// private var mService: ServiceImage<ResponseImage>? = null
|
||||
private var isLoading = AtomicBoolean(false)
|
||||
private var mPage = 1
|
||||
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
binding = PageRecentBinding.inflate(layoutInflater)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
setupViews()
|
||||
}
|
||||
|
||||
private fun setupViews() {
|
||||
|
||||
mAdapter = ImageGridAdapter(requireActivity(), MyApp.myData[0].data)
|
||||
mAdapter?.setOnItemClickListener(object :
|
||||
ImageGridAdapter.OnItemClickListener {
|
||||
override fun onItemClick(pos: Data) {
|
||||
|
||||
toPreview(pos)
|
||||
}
|
||||
})
|
||||
binding.rv.layoutManager = GridLayoutManager(requireActivity(), 3)
|
||||
binding.rv.addItemDecoration(
|
||||
CustomItemDecoration(1, 2)
|
||||
)
|
||||
binding.rv.adapter = mAdapter!!
|
||||
|
||||
// //下拉刷新
|
||||
// binding.refreshLayout.setOnRefreshListener {
|
||||
// if (isLoading.get()) {
|
||||
// return@setOnRefreshListener
|
||||
// }
|
||||
// refresh()
|
||||
// }
|
||||
//
|
||||
// //上拉加载
|
||||
// binding.refreshLayout.setOnLoadMoreListener {
|
||||
// if (isLoading.get()) {
|
||||
// return@setOnLoadMoreListener
|
||||
// }
|
||||
// loadMore()
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
fun updateView() {
|
||||
// binding.refreshLayout.finishRefresh()
|
||||
// binding.refreshLayout.finishLoadMore()
|
||||
if (mList.isNotEmpty()) {
|
||||
binding.tvEmpty.hide()
|
||||
} else {
|
||||
binding.tvEmpty.show()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun toPreview(pos: Data) {
|
||||
// if (pos < 0 || pos >= mList.size) {
|
||||
// return
|
||||
// }
|
||||
if (activity != null) {
|
||||
val listBean = PreviewBean()
|
||||
listBean.list = mList
|
||||
PreviewAbility.start(requireActivity(), pos)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,111 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper.page
|
||||
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.view.GravityCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.fragment.app.FragmentPagerAdapter
|
||||
import com.cute.girl.hd.pink.img.wallpaper.R
|
||||
import com.cute.girl.hd.pink.img.wallpaper.databinding.AbilityMainBinding
|
||||
|
||||
class MainAbility : AppCompatActivity() {
|
||||
private lateinit var binding: AbilityMainBinding
|
||||
private var mFragments: ArrayList<Fragment> = ArrayList()
|
||||
private val mTitles: MutableList<String> = mutableListOf()
|
||||
private var mAdapter: MyPagerAdapter? = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = AbilityMainBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
setupViews()
|
||||
}
|
||||
|
||||
private fun setupViews() {
|
||||
binding.tvVersion.text = "v${getAppVersionName()}"
|
||||
mTitles.add("Recent")
|
||||
mTitles.add("Popular")
|
||||
mTitles.add("Feature")
|
||||
mTitles.add("Category")
|
||||
mFragments.add(RecentPage())
|
||||
mFragments.add(PopularPage())
|
||||
mFragments.add(FeaturePage())
|
||||
mFragments.add(CategoryPage())
|
||||
|
||||
mAdapter = MyPagerAdapter(supportFragmentManager)
|
||||
binding.viewPager.adapter = mAdapter!!
|
||||
|
||||
mAdapter?.notifyDataSetChanged()//必须在viewpager初始化之前先更新mAdapter,否则会报错
|
||||
binding.stlTab.setViewPager(binding.viewPager, mTitles.toTypedArray(), this, mFragments)
|
||||
binding.viewPager.currentItem = 0
|
||||
binding.viewPager.offscreenPageLimit = 4
|
||||
|
||||
binding.ivMenu.setOnClickListener {
|
||||
binding.drawer.openDrawer(GravityCompat.START)
|
||||
}
|
||||
|
||||
binding.rlShare.setOnClickListener {
|
||||
try {
|
||||
val intentShare = Intent()
|
||||
intentShare.action = Intent.ACTION_SEND
|
||||
intentShare.type = "text/plain"
|
||||
intentShare.putExtra(
|
||||
Intent.EXTRA_TEXT,
|
||||
getString(
|
||||
R.string.share_text,
|
||||
"http://play.google.com/store/apps/details?id=${this.packageName}"
|
||||
)
|
||||
)
|
||||
startActivity(intentShare)
|
||||
} catch (ignore: Exception) {
|
||||
}
|
||||
}
|
||||
|
||||
binding.rlRate.setOnClickListener {
|
||||
try {
|
||||
val intent = Intent(
|
||||
Intent.ACTION_VIEW,
|
||||
Uri.parse("http://play.google.com/store/apps/details?id=${this.packageName}")
|
||||
)
|
||||
startActivity(intent)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
binding.rlPrivacy.setOnClickListener {
|
||||
PrivacyAbility.start(this)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getAppVersionName(): String {
|
||||
return try {
|
||||
val pm: PackageManager = this.packageManager
|
||||
val pi = pm.getPackageInfo(this.packageName, 0)
|
||||
if (pi == null) "" else pi.versionName
|
||||
} catch (e: PackageManager.NameNotFoundException) {
|
||||
e.printStackTrace()
|
||||
""
|
||||
}
|
||||
}
|
||||
|
||||
inner class MyPagerAdapter(fm: FragmentManager) : FragmentPagerAdapter(fm) {
|
||||
override fun getCount(): Int {
|
||||
return mFragments.size
|
||||
}
|
||||
|
||||
override fun getPageTitle(position: Int): CharSequence {
|
||||
return mTitles[position]
|
||||
}
|
||||
|
||||
override fun getItem(position: Int): Fragment {
|
||||
return mFragments.get(position)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,188 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper.page
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import com.cute.girl.hd.pink.img.wallpaper.MyApp
|
||||
import com.cute.girl.hd.pink.img.wallpaper.adapter.ImageGridAdapter
|
||||
import com.cute.girl.hd.pink.img.wallpaper.databinding.PageRecentBinding
|
||||
import com.cute.girl.hd.pink.img.wallpaper.entity.Data
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.GlobalExt.hide
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.GlobalExt.show
|
||||
import com.cute.girl.hd.pink.img.wallpaper.view.CustomItemDecoration
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
class PopularPage : Fragment() {
|
||||
private lateinit var binding: PageRecentBinding
|
||||
private lateinit var mList: List<Data>
|
||||
private var mAdapter: ImageGridAdapter? = null
|
||||
// private var mService: ServiceImage<ResponseImage>? = null
|
||||
private var isLoading = AtomicBoolean(false)
|
||||
private var mPage = 1
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
binding = PageRecentBinding.inflate(layoutInflater)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
mList = MyApp.myData[2].data
|
||||
setupViews()
|
||||
}
|
||||
|
||||
|
||||
private fun setupViews() {
|
||||
mAdapter = ImageGridAdapter(requireActivity(), mList)
|
||||
mAdapter?.setOnItemClickListener(object :
|
||||
ImageGridAdapter.OnItemClickListener {
|
||||
override fun onItemClick(pos: Data) {
|
||||
|
||||
toPreview(pos)
|
||||
}
|
||||
})
|
||||
binding.rv.layoutManager = GridLayoutManager(requireActivity(), 3)
|
||||
binding.rv.addItemDecoration(
|
||||
CustomItemDecoration(1, 2)
|
||||
)
|
||||
binding.rv.adapter = mAdapter!!
|
||||
|
||||
// //下拉刷新
|
||||
// binding.refreshLayout.setOnRefreshListener {
|
||||
// if (isLoading.get()) {
|
||||
// return@setOnRefreshListener
|
||||
// }
|
||||
// refresh()
|
||||
// }
|
||||
//
|
||||
// //上拉加载
|
||||
// binding.refreshLayout.setOnLoadMoreListener {
|
||||
// if (isLoading.get()) {
|
||||
// return@setOnLoadMoreListener
|
||||
// }
|
||||
// loadMore()
|
||||
// }
|
||||
|
||||
refresh()
|
||||
}
|
||||
|
||||
private fun refresh() {
|
||||
// if (mService == null) {
|
||||
// mService = ServiceImage()
|
||||
// }
|
||||
// if (isLoading.get()) {
|
||||
// return
|
||||
// }
|
||||
// isLoading.set(true)
|
||||
// mPage = 1
|
||||
// mService?.let { service ->
|
||||
// val call = service.mApi.getPopular(1)
|
||||
// service.callEnqueue(call, object : BaseListener<ResponseImage> {
|
||||
// override fun onResponse(t: ResponseImage?) {
|
||||
// if (t != null) {
|
||||
// if (t.MaterialWallpaper != null && t.MaterialWallpaper.isNotEmpty()) {
|
||||
// mList.clear()
|
||||
// mList.addAll(t.MaterialWallpaper.toMutableList())
|
||||
// isLoading.set(false)
|
||||
// onMain {
|
||||
// mAdapter?.notifyDataSetChanged()
|
||||
// updateView()
|
||||
// }
|
||||
// } else {
|
||||
// onMain {
|
||||
// updateView()
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// onMain {
|
||||
// updateView()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// override fun onFail(e: String?) {
|
||||
// isLoading.set(false)
|
||||
// onMain {
|
||||
// mAdapter?.notifyDataSetChanged()
|
||||
// updateView()
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
}
|
||||
|
||||
private fun loadMore() {
|
||||
// if (mService == null) {
|
||||
// mService = ServiceImage()
|
||||
// }
|
||||
// if (isLoading.get()) {
|
||||
// return
|
||||
// }
|
||||
// isLoading.set(true)
|
||||
// val newPage = mPage + 1
|
||||
// mService?.let { service ->
|
||||
// val call = service.mApi.getPopular(newPage)
|
||||
// service.callEnqueue(call, object : BaseListener<ResponseImage> {
|
||||
// override fun onResponse(t: ResponseImage?) {
|
||||
// if (t != null) {
|
||||
// if (t.MaterialWallpaper != null && t.MaterialWallpaper.isNotEmpty()) {
|
||||
// mList.addAll(t.MaterialWallpaper.toMutableList())
|
||||
// isLoading.set(false)
|
||||
// mPage = newPage
|
||||
// onMain {
|
||||
// mAdapter?.notifyDataSetChanged()
|
||||
// updateView()
|
||||
// }
|
||||
// } else {
|
||||
// onMain {
|
||||
// updateView()
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// onMain {
|
||||
// updateView()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// override fun onFail(e: String?) {
|
||||
// isLoading.set(false)
|
||||
// onMain {
|
||||
// mAdapter?.notifyDataSetChanged()
|
||||
// updateView()
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
}
|
||||
|
||||
fun updateView() {
|
||||
// binding.refreshLayout.finishRefresh()
|
||||
// binding.refreshLayout.finishLoadMore()
|
||||
if (mList.isNotEmpty()) {
|
||||
binding.tvEmpty.hide()
|
||||
} else {
|
||||
binding.tvEmpty.show()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun toPreview(pos: Data) {
|
||||
// if (pos < 0 || pos >= mList.size) {
|
||||
// return
|
||||
// }
|
||||
if (activity != null) {
|
||||
// val listBean = PreviewBean()
|
||||
// listBean.list = mList
|
||||
PreviewAbility.start(requireActivity(), pos)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,404 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper.page
|
||||
|
||||
import android.app.WallpaperManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.view.WindowManager
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
import com.applovin.mediation.MaxAd
|
||||
import com.applovin.mediation.ads.MaxInterstitialAd
|
||||
import com.cute.girl.hd.pink.img.wallpaper.R
|
||||
import com.cute.girl.hd.pink.img.wallpaper.adapter.ImagePagerAdapter
|
||||
import com.cute.girl.hd.pink.img.wallpaper.databinding.AbilityPreviewBinding
|
||||
import com.cute.girl.hd.pink.img.wallpaper.entity.Data
|
||||
import com.cute.girl.hd.pink.img.wallpaper.entity.GImage
|
||||
import com.cute.girl.hd.pink.img.wallpaper.entity.IntentConstants
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.DownloadUtil
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.GlobalExt.getString
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.GlobalExt.hide
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.GlobalExt.onMain
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.GlobalExt.show
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.MediaUtil
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.PermissionUtil
|
||||
import com.cute.girl.hd.pink.img.wallpaper.view.SetAsDialog
|
||||
import com.cute.girl.hd.pink.img.wallpaper.entity.PreviewBean
|
||||
import com.cute.girl.hd.pink.img.wallpaper.mymax.MaxCallBack
|
||||
import com.cute.girl.hd.pink.img.wallpaper.mymax.MaxUtils
|
||||
import com.liulishuo.filedownloader.BaseDownloadTask
|
||||
import com.liulishuo.filedownloader.FileDownloadListener
|
||||
import com.liulishuo.filedownloader.FileDownloader
|
||||
import kotlinx.coroutines.launch
|
||||
import pub.devrel.easypermissions.EasyPermissions
|
||||
import java.io.File
|
||||
|
||||
class PreviewAbility : AppCompatActivity(), EasyPermissions.PermissionCallbacks {
|
||||
private lateinit var binding: AbilityPreviewBinding
|
||||
private var mList: MutableList<Data> = mutableListOf()
|
||||
private var mCurPos: Int = 0
|
||||
private var mImagePagerAdapter: ImagePagerAdapter? = null
|
||||
private var mSetAsDialog: SetAsDialog? = null
|
||||
private var mAction = 0//0设置壁纸 1下载壁纸
|
||||
|
||||
private lateinit var adList: List<MaxInterstitialAd>
|
||||
|
||||
companion object {
|
||||
fun start(context: Context, bean: Data) {
|
||||
val intent = Intent(context, PreviewAbility::class.java)
|
||||
intent.putExtra(IntentConstants.KEY_LIST, bean)
|
||||
// intent.putExtra(IntentConstants.KEY_POS, pos)
|
||||
context.startActivity(intent)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = AbilityPreviewBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
adList = MaxUtils.getAllAd()
|
||||
setupViews()
|
||||
}
|
||||
|
||||
private fun showMyMAx(action: () -> Unit) {
|
||||
val onCache = MaxUtils.onCache(adList)
|
||||
if (onCache != null) {
|
||||
MaxUtils.setMAXCAllBack(onCache, object : MaxCallBack {
|
||||
override fun onShowFail(ad: MaxAd?) {
|
||||
action.invoke()
|
||||
}
|
||||
|
||||
override fun onAdHidden() {
|
||||
action.invoke()
|
||||
adList = MaxUtils.getAllAd()
|
||||
}
|
||||
|
||||
})
|
||||
onCache.showAd(this)
|
||||
} else {
|
||||
action.invoke()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupViews() {
|
||||
//隐藏状态栏和底部导航栏
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
|
||||
window.decorView.systemUiVisibility =
|
||||
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_FULLSCREEN
|
||||
|
||||
initData()
|
||||
setUpView()
|
||||
}
|
||||
|
||||
private fun initData() {
|
||||
var listBean: Data? = null
|
||||
if (intent.hasExtra(IntentConstants.KEY_LIST)) {
|
||||
listBean = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
intent.getSerializableExtra(IntentConstants.KEY_LIST, Data::class.java)
|
||||
} else {
|
||||
intent.getSerializableExtra(IntentConstants.KEY_LIST) as Data?
|
||||
}
|
||||
}
|
||||
if (listBean == null) {
|
||||
finish()
|
||||
return
|
||||
}
|
||||
mList.clear()
|
||||
mList.add(listBean)
|
||||
|
||||
if (mList.size == 0) {
|
||||
finish()
|
||||
return
|
||||
}
|
||||
|
||||
mCurPos = intent.getIntExtra(IntentConstants.KEY_POS, 0)
|
||||
|
||||
if (mCurPos < 0 || mCurPos >= mList.size) {
|
||||
finish()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
private fun setUpView() {
|
||||
mImagePagerAdapter = ImagePagerAdapter(this, mList)
|
||||
mImagePagerAdapter?.setOnItemClickListener(object :
|
||||
ImagePagerAdapter.OnItemClickListener {
|
||||
override fun onItemClick(pos: Int) {
|
||||
|
||||
}
|
||||
})
|
||||
binding.viewPager.adapter = mImagePagerAdapter!!
|
||||
binding.viewPager.setCurrentItem(mCurPos, false)
|
||||
binding.viewPager.registerOnPageChangeCallback(object :
|
||||
ViewPager2.OnPageChangeCallback() {
|
||||
override fun onPageSelected(position: Int) {
|
||||
mCurPos = position
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
binding.ivBack.setOnClickListener {
|
||||
finish()
|
||||
}
|
||||
|
||||
binding.tvSet.setOnClickListener {
|
||||
mAction = 0
|
||||
if (isExist()) {
|
||||
set4KWallpaper()
|
||||
} else {
|
||||
startDownload()
|
||||
}
|
||||
}
|
||||
|
||||
binding.tvDownload.setOnClickListener {
|
||||
showMyMAx {
|
||||
doSave()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
mSetAsDialog?.dismiss()
|
||||
}
|
||||
|
||||
private fun isExist(): Boolean {
|
||||
return DownloadUtil.isExist(
|
||||
mList[mCurPos].sourceURl,
|
||||
mList[mCurPos].getTag()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
private fun set4KWallpaper() {
|
||||
val image = mList[mCurPos]
|
||||
val path =
|
||||
DownloadUtil.getFilePath(
|
||||
image.sourceURl,
|
||||
image.getTag()
|
||||
)
|
||||
val file = File(path)
|
||||
if (!file.exists()) {
|
||||
return
|
||||
}
|
||||
val wallpaperManager = WallpaperManager.getInstance(this)
|
||||
if (mSetAsDialog == null) {
|
||||
mSetAsDialog = SetAsDialog(this) {
|
||||
onClickHomeScreen = {
|
||||
|
||||
showMyMAx {
|
||||
lifecycleScope.launch {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
|
||||
wallpaperManager.setStream(file.inputStream())
|
||||
} else {
|
||||
wallpaperManager.setStream(
|
||||
file.inputStream(),
|
||||
null,
|
||||
true,
|
||||
WallpaperManager.FLAG_SYSTEM
|
||||
)
|
||||
}
|
||||
onMain {
|
||||
Toast.makeText(
|
||||
this@PreviewAbility,
|
||||
R.string.set_success.getString(),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
onClickLockScreen = {
|
||||
|
||||
showMyMAx {
|
||||
lifecycleScope.launch {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
|
||||
wallpaperManager.setStream(file.inputStream())
|
||||
} else {
|
||||
wallpaperManager.setStream(
|
||||
file.inputStream(),
|
||||
null,
|
||||
true,
|
||||
WallpaperManager.FLAG_LOCK
|
||||
)
|
||||
}
|
||||
onMain {
|
||||
Toast.makeText(
|
||||
this@PreviewAbility,
|
||||
R.string.set_success.getString(),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
onClickBoth = {
|
||||
showMyMAx {
|
||||
lifecycleScope.launch {
|
||||
wallpaperManager.setStream(file.inputStream())//FLAG_SYSTEM | FLAG_LOCK)
|
||||
onMain {
|
||||
Toast.makeText(
|
||||
this@PreviewAbility,
|
||||
R.string.set_success.getString(),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
mSetAsDialog?.show()
|
||||
}
|
||||
|
||||
private fun doSave() {
|
||||
if (!PermissionUtil.hasStoragePermission(this)) {
|
||||
PermissionUtil.requestStoragePermission(this)
|
||||
return
|
||||
}
|
||||
clickSave()
|
||||
}
|
||||
|
||||
private fun clickSave() {
|
||||
mAction = 1
|
||||
if (isExist()) {
|
||||
saveWallpaper()
|
||||
} else {
|
||||
startDownload()
|
||||
}
|
||||
}
|
||||
|
||||
private fun startDownload() {
|
||||
if (isFinishing) {
|
||||
return
|
||||
}
|
||||
val filePath = DownloadUtil.getFilePath(mList[mCurPos].sourceURl, mList[mCurPos].getTag())
|
||||
Log.d(
|
||||
"-----------",
|
||||
"---------startDownload-${mList[mCurPos].sourceURl} filePath=${filePath}"
|
||||
)
|
||||
binding.flDownload.show()
|
||||
FileDownloader.getImpl().create(mList[mCurPos].sourceURl)
|
||||
.setPath(filePath)
|
||||
.setCallbackProgressTimes(300)
|
||||
.setMinIntervalUpdateSpeed(400)
|
||||
.setListener(object : FileDownloadListener() {
|
||||
override fun pending(task: BaseDownloadTask?, soFarBytes: Int, totalBytes: Int) {
|
||||
|
||||
}
|
||||
|
||||
override fun progress(task: BaseDownloadTask?, soFarBytes: Int, totalBytes: Int) {
|
||||
if (!isFinishing) {
|
||||
binding.pbb.show()
|
||||
}
|
||||
}
|
||||
|
||||
override fun completed(task: BaseDownloadTask?) {
|
||||
Log.d("-----------", "---------completed")
|
||||
if (!isFinishing) {
|
||||
binding.flDownload.hide()
|
||||
mImagePagerAdapter?.notifyItemChanged(mCurPos)
|
||||
if (mAction == 0) {
|
||||
set4KWallpaper()
|
||||
} else {
|
||||
saveWallpaper()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun paused(task: BaseDownloadTask?, soFarBytes: Int, totalBytes: Int) {
|
||||
if (!isFinishing) {
|
||||
binding.flDownload.hide()
|
||||
Toast.makeText(
|
||||
this@PreviewAbility,
|
||||
R.string.download_failed,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
|
||||
override fun error(task: BaseDownloadTask?, e: Throwable?) {
|
||||
if (!isFinishing) {
|
||||
binding.flDownload.hide()
|
||||
Toast.makeText(
|
||||
this@PreviewAbility,
|
||||
R.string.download_failed,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
|
||||
override fun warn(task: BaseDownloadTask?) {
|
||||
if (!isFinishing) {
|
||||
binding.flDownload.hide()
|
||||
Toast.makeText(
|
||||
this@PreviewAbility,
|
||||
R.string.download_failed,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
|
||||
}).start()
|
||||
}
|
||||
|
||||
private fun saveWallpaper() {
|
||||
val image = mList[mCurPos]
|
||||
val path =
|
||||
DownloadUtil.getFilePath(
|
||||
image.sourceURl,
|
||||
image.getTag()
|
||||
)
|
||||
val saved = MediaUtil.saveImageToSystemAlbum(path, this@PreviewAbility)
|
||||
if (!isFinishing) {
|
||||
if (saved) {
|
||||
Toast.makeText(
|
||||
this@PreviewAbility,
|
||||
R.string.saved_to_album,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
} else {
|
||||
Toast.makeText(
|
||||
this@PreviewAbility,
|
||||
R.string.save_failed,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
override fun onRequestPermissionsResult(
|
||||
requestCode: Int,
|
||||
permissions: Array<out String>,
|
||||
grantResults: IntArray
|
||||
) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this)
|
||||
}
|
||||
|
||||
override fun onPermissionsGranted(requestCode: Int, perms: MutableList<String>) {
|
||||
if (requestCode == PermissionUtil.REQUEST_CODE_PERMISSION_STORAGE) {
|
||||
doSave()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPermissionsDenied(requestCode: Int, perms: MutableList<String>) {
|
||||
if (requestCode == PermissionUtil.REQUEST_CODE_PERMISSION_STORAGE) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,68 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper.page
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.webkit.WebSettings
|
||||
import android.webkit.WebView
|
||||
import android.webkit.WebViewClient
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.cute.girl.hd.pink.img.wallpaper.R
|
||||
import com.cute.girl.hd.pink.img.wallpaper.databinding.AbilityPrivacyBinding
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.GlobalExt.getString
|
||||
|
||||
class PrivacyAbility : AppCompatActivity() {
|
||||
private lateinit var binding: AbilityPrivacyBinding
|
||||
|
||||
companion object {
|
||||
const val URL_PRIVACY: String = "https://artwallpaper.bitbucket.io/privacy.html"
|
||||
|
||||
fun start(context: Context) {
|
||||
context.startActivity(Intent(context, PrivacyAbility::class.java))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = AbilityPrivacyBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
setupViews()
|
||||
}
|
||||
|
||||
@SuppressLint("SetJavaScriptEnabled")
|
||||
private fun setupViews() {
|
||||
binding.tvTitle.text = R.string.privacy_policy.getString()
|
||||
|
||||
val webSettings: WebSettings = binding.webView.settings
|
||||
webSettings.javaScriptEnabled = true // enable javascript
|
||||
webSettings.javaScriptCanOpenWindowsAutomatically = true
|
||||
binding.webView.webViewClient = object : WebViewClient() {
|
||||
override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
|
||||
if (url.startsWith("http:") || url.startsWith("https:")) {
|
||||
return false
|
||||
}
|
||||
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
|
||||
startActivity(intent)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onReceivedError(
|
||||
view: WebView,
|
||||
errorCode: Int,
|
||||
description: String,
|
||||
failingUrl: String
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
binding.webView.loadUrl(URL_PRIVACY)
|
||||
binding.ivBack.visibility = View.VISIBLE
|
||||
|
||||
binding.ivBack.setOnClickListener {
|
||||
onBackPressed()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,193 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper.page
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import com.cute.girl.hd.pink.img.wallpaper.MyApp
|
||||
import com.cute.girl.hd.pink.img.wallpaper.adapter.ImageGridAdapter
|
||||
import com.cute.girl.hd.pink.img.wallpaper.databinding.PageRecentBinding
|
||||
import com.cute.girl.hd.pink.img.wallpaper.entity.Data
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.GlobalExt.hide
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.GlobalExt.show
|
||||
import com.cute.girl.hd.pink.img.wallpaper.view.CustomItemDecoration
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
class RecentPage : Fragment() {
|
||||
private lateinit var binding: PageRecentBinding
|
||||
private lateinit var mList: List<Data>
|
||||
private var mAdapter: ImageGridAdapter? = null
|
||||
// private var mService: ServiceImage<ResponseImage>? = null
|
||||
private var isLoading = AtomicBoolean(false)
|
||||
private var mPage = 1
|
||||
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
binding = PageRecentBinding.inflate(layoutInflater)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
mList = MyApp.myData[1].data
|
||||
setupViews()
|
||||
}
|
||||
|
||||
private fun setupViews() {
|
||||
mAdapter = ImageGridAdapter(requireActivity(), mList)
|
||||
mAdapter?.setOnItemClickListener(object :
|
||||
ImageGridAdapter.OnItemClickListener {
|
||||
override fun onItemClick(pos: Data) {
|
||||
|
||||
toPreview(pos)
|
||||
}
|
||||
})
|
||||
binding.rv.layoutManager = GridLayoutManager(requireActivity(), 3)
|
||||
binding.rv.addItemDecoration(
|
||||
CustomItemDecoration(1, 2)
|
||||
)
|
||||
binding.rv.adapter = mAdapter!!
|
||||
|
||||
// //下拉刷新
|
||||
// binding.refreshLayout.setOnRefreshListener {
|
||||
// if (isLoading.get()) {
|
||||
// return@setOnRefreshListener
|
||||
// }
|
||||
// refresh()
|
||||
// }
|
||||
//
|
||||
// //上拉加载
|
||||
// binding.refreshLayout.setOnLoadMoreListener {
|
||||
// if (isLoading.get()) {
|
||||
// return@setOnLoadMoreListener
|
||||
// }
|
||||
// loadMore()
|
||||
// }
|
||||
|
||||
// refresh()
|
||||
}
|
||||
private fun refresh(){
|
||||
val shuffled = mList.shuffled()
|
||||
mAdapter?.refresh(shuffled)
|
||||
|
||||
}
|
||||
// private fun refresh() {
|
||||
// if (mService == null) {
|
||||
// mService = ServiceImage()
|
||||
// }
|
||||
// if (isLoading.get()) {
|
||||
// return
|
||||
// }
|
||||
// isLoading.set(true)
|
||||
// mPage = 1
|
||||
// mService?.let { service ->
|
||||
// val call = service.mApi.getRecent(1)
|
||||
// service.callEnqueue(call, object : BaseListener<ResponseImage> {
|
||||
// override fun onResponse(t: ResponseImage?) {
|
||||
// if (t != null) {
|
||||
// if (t.MaterialWallpaper != null && t.MaterialWallpaper.isNotEmpty()) {
|
||||
// mList.clear()
|
||||
// mList.addAll(t.MaterialWallpaper.toMutableList())
|
||||
// isLoading.set(false)
|
||||
// onMain {
|
||||
// mAdapter?.notifyDataSetChanged()
|
||||
// updateView()
|
||||
// }
|
||||
// } else {
|
||||
// onMain {
|
||||
// updateView()
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// onMain {
|
||||
// updateView()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// override fun onFail(e: String?) {
|
||||
// isLoading.set(false)
|
||||
// onMain {
|
||||
// mAdapter?.notifyDataSetChanged()
|
||||
// updateView()
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
|
||||
private fun loadMore(){
|
||||
|
||||
}
|
||||
|
||||
// private fun loadMore() {
|
||||
// if (mService == null) {
|
||||
// mService = ServiceImage()
|
||||
// }
|
||||
// if (isLoading.get()) {
|
||||
// return
|
||||
// }
|
||||
// isLoading.set(true)
|
||||
// val newPage = mPage + 1
|
||||
// mService?.let { service ->
|
||||
// val call = service.mApi.getRecent(newPage)
|
||||
// service.callEnqueue(call, object : BaseListener<ResponseImage> {
|
||||
// override fun onResponse(t: ResponseImage?) {
|
||||
// if (t != null) {
|
||||
// if (t.MaterialWallpaper != null && t.MaterialWallpaper.isNotEmpty()) {
|
||||
// mList.addAll(t.MaterialWallpaper.toMutableList())
|
||||
// isLoading.set(false)
|
||||
// mPage = newPage
|
||||
// onMain {
|
||||
// mAdapter?.notifyDataSetChanged()
|
||||
// updateView()
|
||||
// }
|
||||
// } else {
|
||||
// onMain {
|
||||
// updateView()
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// onMain {
|
||||
// updateView()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// override fun onFail(e: String?) {
|
||||
// isLoading.set(false)
|
||||
// onMain {
|
||||
// mAdapter?.notifyDataSetChanged()
|
||||
// updateView()
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
|
||||
fun updateView() {
|
||||
// binding.refreshLayout.finishRefresh()
|
||||
// binding.refreshLayout.finishLoadMore()
|
||||
if (mList.isNotEmpty()) {
|
||||
binding.tvEmpty.hide()
|
||||
} else {
|
||||
binding.tvEmpty.show()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun toPreview(data: Data) {
|
||||
if (activity != null) {
|
||||
// val listBean = PreviewBean()
|
||||
// listBean.list = mList
|
||||
PreviewAbility.start(requireActivity(), data)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,94 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper.page
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.os.Bundle
|
||||
import android.os.CountDownTimer
|
||||
import android.util.Log
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
||||
import com.applovin.mediation.MaxAd
|
||||
import com.applovin.mediation.ads.MaxInterstitialAd
|
||||
import com.cute.girl.hd.pink.img.wallpaper.MyApp
|
||||
import com.cute.girl.hd.pink.img.wallpaper.databinding.AbilityStartBinding
|
||||
import com.cute.girl.hd.pink.img.wallpaper.mymax.MaxCallBack
|
||||
import com.cute.girl.hd.pink.img.wallpaper.mymax.MaxUtils
|
||||
|
||||
class StartAbility : AppCompatActivity() {
|
||||
private lateinit var binding: AbilityStartBinding
|
||||
|
||||
private var time =10000L
|
||||
private var needShow = true
|
||||
|
||||
private lateinit var countDownTimer: CountDownTimer
|
||||
private lateinit var lists:List<MaxInterstitialAd>
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = AbilityStartBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
||||
countDownTimer = object : CountDownTimer(time,100){
|
||||
override fun onTick(millisUntilFinished: Long) {
|
||||
if (needShow) {
|
||||
ShowAd {}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFinish() {
|
||||
if (needShow) {
|
||||
ShowAd {
|
||||
setupViews()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
startAd()
|
||||
}
|
||||
private fun startAd() {
|
||||
if (!MyApp.initSDK) {
|
||||
LocalBroadcastManager.getInstance(this).registerReceiver(object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
loadAdGo()
|
||||
Log.d("------------","------------1sucess")
|
||||
}
|
||||
}, IntentFilter(MyApp.AD_INIT_ACTION))
|
||||
} else {
|
||||
loadAdGo()
|
||||
Log.d("------------","------------2sucess")
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadAdGo() {
|
||||
lists = MaxUtils.getAllAd()
|
||||
countDownTimer.start()
|
||||
}
|
||||
|
||||
private fun setupViews() {
|
||||
startActivity(Intent(this@StartAbility, MainAbility::class.java))
|
||||
finish()
|
||||
}
|
||||
|
||||
private fun ShowAd(action: () -> Unit) {
|
||||
val checkCacheAd = MaxUtils.onCache(lists)
|
||||
if (checkCacheAd == null) {
|
||||
action.invoke()
|
||||
} else {
|
||||
needShow = false
|
||||
MaxUtils.setMAXCAllBack(checkCacheAd, object : MaxCallBack {
|
||||
override fun onShowFail(ad: MaxAd?) {
|
||||
setupViews()
|
||||
}
|
||||
|
||||
override fun onAdHidden() {
|
||||
setupViews()
|
||||
}
|
||||
})
|
||||
checkCacheAd.showAd()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper.utils
|
||||
|
||||
import android.content.Context
|
||||
import com.cute.girl.hd.pink.img.wallpaper.MyApp
|
||||
|
||||
|
||||
object DeviceUtil {
|
||||
|
||||
fun dp2Px(dp: Int): Int {
|
||||
val scale: Float = MyApp.app.resources.displayMetrics.density
|
||||
return (dp * scale + 0.5f).toInt()
|
||||
}
|
||||
|
||||
fun dp2Px(dp: Float): Float {
|
||||
val scale: Float = MyApp.app.resources.displayMetrics.density
|
||||
return dp * scale + 0.5f
|
||||
}
|
||||
|
||||
|
||||
fun getScreenHeight(context: Context): Int {
|
||||
return context.resources.displayMetrics.heightPixels
|
||||
}
|
||||
|
||||
|
||||
fun getScreenWidth(context: Context): Int {
|
||||
return context.resources.displayMetrics.widthPixels
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,49 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper.utils
|
||||
|
||||
import android.net.Uri
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import java.io.File
|
||||
|
||||
object DownloadUtil {
|
||||
|
||||
|
||||
/**
|
||||
* https://3dparallax.online/3DParallax/assets/4D/186/img.jpg
|
||||
* 获取下载文件的名称 + 后缀名
|
||||
* tag是用来区分当文件名称一样的情况
|
||||
*/
|
||||
fun getFileName(url: String, tag: String?): String {
|
||||
return if (TextUtils.isEmpty(tag)) {
|
||||
url.substring(url.lastIndexOf("/") + 1)
|
||||
} else {
|
||||
tag + url.substring(url.lastIndexOf("/") + 1)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件下载路径
|
||||
* path:/storage/emulated/0/Android/data/com.lux.sound.pranks.hilarious.effects/X4D/download/hairclipper_4.jpg
|
||||
*/
|
||||
fun getFilePath(url: String, tag: String?): String {
|
||||
|
||||
val s = FileUtil.getDownloadDirectory() + File.separator + tag
|
||||
Log.d("--------","----getFilePath--$s")
|
||||
return s
|
||||
}
|
||||
|
||||
fun getFile(url: String, tag: String?): File {
|
||||
return File(getFilePath(url, tag))
|
||||
}
|
||||
|
||||
fun getFileUri(url: String, tag: String?): Uri {
|
||||
return Uri.fromFile(File(getFilePath(url, tag)))
|
||||
}
|
||||
|
||||
/**
|
||||
* @param url 文件网络地址http://dadaad.png
|
||||
*/
|
||||
fun isExist(url: String, tag: String?): Boolean {
|
||||
return File(getFilePath(url, tag)).exists()
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,219 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper.utils
|
||||
|
||||
import android.content.ContentResolver
|
||||
import android.content.ContentUris
|
||||
import android.content.Context
|
||||
import android.database.Cursor
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Environment
|
||||
import android.provider.DocumentsContract
|
||||
import android.provider.MediaStore
|
||||
import com.cute.girl.hd.pink.img.wallpaper.MyApp
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
|
||||
|
||||
object FileUtil {
|
||||
private const val DIR_FILE_NAME = "PrankSound"
|
||||
private const val DIR_DOWNLOAD = "download"
|
||||
private const val DIR_CREATE = "create"
|
||||
|
||||
/**
|
||||
* 文件下载路径
|
||||
*/
|
||||
private fun getDefaultDirectory(): String {
|
||||
var dirName = ""
|
||||
if (MyApp.app.getExternalFilesDir(DIR_FILE_NAME) != null) {//外部存储可用
|
||||
if (Build.VERSION.SDK_INT >= 29) {
|
||||
dirName = MyApp.app.getExternalFilesDir(DIR_FILE_NAME)!!.path
|
||||
} else if (Build.VERSION.SDK_INT < 29) {
|
||||
dirName = MyApp.app.getExternalFilesDir(DIR_FILE_NAME)!!.absolutePath
|
||||
}
|
||||
} else {//外部存储不可用
|
||||
dirName = MyApp.app.filesDir.absolutePath
|
||||
}
|
||||
return dirName
|
||||
}
|
||||
|
||||
/**
|
||||
* /storage/emulated/0/Android/data/com.prank.sounds.funny.toy.fart.haircut/cache/download
|
||||
*/
|
||||
fun getDownloadDirectory(): String {
|
||||
return getDefaultDirectory() + File.separator + DIR_DOWNLOAD
|
||||
}
|
||||
|
||||
/**
|
||||
* /storage/emulated/0/Android/data/com.prank.sounds.funny.toy.fart.haircut/cache/tape
|
||||
*/
|
||||
fun getCreateDirectory(): String {
|
||||
return getDefaultDirectory() + File.separator + DIR_CREATE
|
||||
}
|
||||
|
||||
/**
|
||||
* @param path 文件绝对路径
|
||||
*/
|
||||
fun isExists(path: String): Boolean {
|
||||
return File(path).exists()
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取下载文件的名称 + 后缀名
|
||||
*/
|
||||
fun getFileNameAndSuffix(path: String): String {
|
||||
return path.substring(path.lastIndexOf("/") + 1)
|
||||
}
|
||||
|
||||
fun getFileName(path: String): String? {
|
||||
val start = path.lastIndexOf("/")
|
||||
val end = path.lastIndexOf(".")
|
||||
return if (start != -1 && end != -1) {
|
||||
path.substring(start + 1, end)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 1.URI 为 content://com.android.providers.media.documents/document/image%3A235700
|
||||
* 因为在 Android 4.4 及以上的机型,使用了 DocumentUri 来代表获取到文件的 URI
|
||||
* 要对于 DocumentUri 进行适配
|
||||
* 2.URI 为 content://media/extenral/images/media/17766 而我们需要得到对应的文件路径。
|
||||
* 参考:https://blog.csdn.net/rjc_lihui/article/details/127020909
|
||||
*/
|
||||
fun getFilePathByUri(context: Context, uri: Uri): String? {
|
||||
var path: String? = null
|
||||
// 以 file:// 开头的
|
||||
if (ContentResolver.SCHEME_FILE == uri.scheme) {
|
||||
path = uri.path
|
||||
return path
|
||||
}
|
||||
// 以 content:// 开头的,比如 content://media/extenral/images/media/17766
|
||||
if (ContentResolver.SCHEME_CONTENT == uri.scheme && Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
|
||||
val cursor = context.contentResolver.query(
|
||||
uri,
|
||||
arrayOf(MediaStore.Images.Media.DATA),
|
||||
null,
|
||||
null,
|
||||
null
|
||||
)
|
||||
if (cursor != null) {
|
||||
if (cursor.moveToFirst()) {
|
||||
val columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)
|
||||
if (columnIndex > -1) {
|
||||
path = cursor.getString(columnIndex)
|
||||
}
|
||||
}
|
||||
cursor.close()
|
||||
}
|
||||
return path
|
||||
}
|
||||
// 4.4及之后的 是以 content:// 开头的,比如 content://com.android.providers.media.documents/document/image%3A235700
|
||||
if (ContentResolver.SCHEME_CONTENT == uri.scheme && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
if (DocumentsContract.isDocumentUri(context, uri)) {
|
||||
if (isExternalStorageDocument(uri)) {
|
||||
// ExternalStorageProvider
|
||||
val docId = DocumentsContract.getDocumentId(uri)
|
||||
val split = docId.split(":".toRegex()).dropLastWhile { it.isEmpty() }
|
||||
.toTypedArray()
|
||||
val type = split[0]
|
||||
if ("primary".equals(type, ignoreCase = true)) {
|
||||
path = Environment.getExternalStorageDirectory().toString() + "/" + split[1]
|
||||
return path
|
||||
}
|
||||
} else if (isDownloadsDocument(uri)) {
|
||||
// DownloadsProvider
|
||||
val id = DocumentsContract.getDocumentId(uri)
|
||||
val contentUri = ContentUris.withAppendedId(
|
||||
Uri.parse("content://downloads/public_downloads"),
|
||||
java.lang.Long.valueOf(id)
|
||||
)
|
||||
path = getDataColumn(context, contentUri, null, null)
|
||||
return path
|
||||
} else if (isMediaDocument(uri)) {
|
||||
// MediaProvider
|
||||
val docId = DocumentsContract.getDocumentId(uri)
|
||||
val split = docId.split(":".toRegex()).dropLastWhile { it.isEmpty() }
|
||||
.toTypedArray()
|
||||
val type = split[0]
|
||||
var contentUri: Uri? = null
|
||||
if ("image" == type) {
|
||||
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
|
||||
} else if ("video" == type) {
|
||||
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
|
||||
} else if ("audio" == type) {
|
||||
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
|
||||
}
|
||||
val selection = "_id=?"
|
||||
val selectionArgs = arrayOf(split[1])
|
||||
path = getDataColumn(context, contentUri, selection, selectionArgs)
|
||||
return path
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun getDataColumn(
|
||||
context: Context,
|
||||
uri: Uri?,
|
||||
selection: String?,
|
||||
selectionArgs: Array<String>?
|
||||
): String? {
|
||||
var cursor: Cursor? = null
|
||||
val column = "_data"
|
||||
val projection = arrayOf(column)
|
||||
try {
|
||||
cursor =
|
||||
context.contentResolver.query(uri!!, projection, selection, selectionArgs, null)
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
val column_index = cursor.getColumnIndexOrThrow(column)
|
||||
return cursor.getString(column_index)
|
||||
}
|
||||
} finally {
|
||||
cursor?.close()
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun isExternalStorageDocument(uri: Uri): Boolean {
|
||||
return "com.android.externalstorage.documents" == uri.authority
|
||||
}
|
||||
|
||||
private fun isDownloadsDocument(uri: Uri): Boolean {
|
||||
return "com.android.providers.downloads.documents" == uri.authority
|
||||
}
|
||||
|
||||
private fun isMediaDocument(uri: Uri): Boolean {
|
||||
return "com.android.providers.media.documents" == uri.authority
|
||||
}
|
||||
|
||||
fun getFileName(contentResolver: ContentResolver, uri: Uri): String? {
|
||||
val projection = arrayOf(MediaStore.MediaColumns.DISPLAY_NAME)
|
||||
contentResolver.query(uri, projection, null, null, null)?.use {
|
||||
if (it.moveToFirst()) {
|
||||
return it.getString(0)
|
||||
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun getFileInputStream(fileUri: Uri): InputStream? =
|
||||
try {
|
||||
MyApp.app.contentResolver.openInputStream(fileUri)
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
null
|
||||
}
|
||||
|
||||
fun getFileOutStream(fileName: String): OutputStream? =
|
||||
try {
|
||||
MyApp.app.openFileOutput(fileName, Context.MODE_PRIVATE)
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
null
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper.utils
|
||||
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.view.View
|
||||
|
||||
object GlobalExt {
|
||||
fun onMain(operation: () -> Unit) = Handler(Looper.getMainLooper()).post(operation)
|
||||
|
||||
fun Int.getString(): String = ResourceUtil.getString(this)
|
||||
fun Int.getColor(): Int = ResourceUtil.getColor(this)
|
||||
fun Int.getDrawable(): Drawable? = ResourceUtil.getDrawable(this)
|
||||
|
||||
fun Int.dp2PxInt(): Int = ResourceUtil.dp2Px(this)
|
||||
fun Int.dp2PxFloat(): Float = ResourceUtil.dp2Px(this).toFloat()
|
||||
|
||||
fun View.show() {
|
||||
this.visibility = View.VISIBLE
|
||||
}
|
||||
fun View.hide() {
|
||||
this.visibility = View.GONE
|
||||
}
|
||||
fun View.invisible() {
|
||||
this.visibility = View.INVISIBLE
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,205 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper.utils
|
||||
|
||||
import android.content.ContentValues
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Environment
|
||||
import android.provider.MediaStore
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
|
||||
|
||||
/**
|
||||
* 从 Android 10 开始向共享存储中添加文件不需要任何权限。
|
||||
* Android 10+ 在没有"android.permission.MANAGE_EXTERNAL_STORAGE"权限的情况下只能使用 MediaStore API方式来存储图片和文件
|
||||
* 如果你的 App 只在共享存储中添加文件,你可以停止在 Android 10+ 上申请任何权限。
|
||||
* 在 Android 13 上废弃了 READ_EXTERNAL_STORAGE 和 WRITE_EXTERNAL_STORAGE 权限
|
||||
*/
|
||||
object MediaUtil {
|
||||
|
||||
private fun getSavePath(): String {
|
||||
return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
|
||||
// android 10 以下版本
|
||||
"${Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).absolutePath}${File.separator}PinkWallpaper"
|
||||
} else {
|
||||
"${Environment.DIRECTORY_PICTURES}${File.separator}PinkWallpaper"
|
||||
}
|
||||
}
|
||||
|
||||
fun saveImageToSystemAlbum(imagePath: String, context: Context): Boolean {
|
||||
return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
|
||||
saveImage(imagePath, context)
|
||||
} else {
|
||||
saveImageQ(imagePath, context)
|
||||
}
|
||||
}
|
||||
|
||||
fun saveVideoToSystemAlbum(imagePath: String, context: Context): Boolean {
|
||||
return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
|
||||
saveVideo(imagePath, context)
|
||||
} else {
|
||||
saveVideoQ(imagePath, context)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将图片保存到系统图库
|
||||
*
|
||||
* @param imagePath
|
||||
* @param context
|
||||
*/
|
||||
private fun saveImageQ(imagePath: String, context: Context): Boolean {
|
||||
return try {
|
||||
val contentResolver = context.contentResolver
|
||||
val contentValues =
|
||||
getImageContentValues(File(imagePath))
|
||||
val localUri = contentResolver.insert(
|
||||
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
|
||||
contentValues
|
||||
)
|
||||
// 拷贝到指定uri,如果没有这步操作,android11不会在相册显示
|
||||
val out = context.contentResolver.openOutputStream(localUri!!)
|
||||
copyFile(imagePath, out)
|
||||
|
||||
contentValues.clear();
|
||||
contentValues.put(MediaStore.MediaColumns.IS_PENDING, 0);
|
||||
contentValues.putNull(MediaStore.MediaColumns.DATE_EXPIRES);
|
||||
contentResolver.update(localUri, contentValues, null, null);
|
||||
true
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
private fun saveImage(imagePath: String, context: Context): Boolean {
|
||||
return try {
|
||||
val path = getSavePath() + File.separator + File(imagePath).name
|
||||
val newFile = File(path)
|
||||
if (!newFile!!.parentFile.exists()) {
|
||||
newFile!!.parentFile.mkdirs()
|
||||
}
|
||||
val out = newFile.outputStream()
|
||||
copyFile(imagePath, out)
|
||||
|
||||
val uri = Uri.fromFile(newFile)
|
||||
context.sendBroadcast(Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri))
|
||||
out.close()
|
||||
true
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun getImageContentValues(paramFile: File): ContentValues {
|
||||
val time = System.currentTimeMillis()
|
||||
val localContentValues = ContentValues()
|
||||
localContentValues.put(MediaStore.Images.Media.TITLE, paramFile.name)
|
||||
localContentValues.put(MediaStore.Images.Media.DISPLAY_NAME, paramFile.name)
|
||||
localContentValues.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg")
|
||||
localContentValues.put(MediaStore.Images.Media.RELATIVE_PATH, getSavePath())
|
||||
// localContentValues.put(MediaStore.Images.Media.DATE_MODIFIED, time / 1000)
|
||||
// localContentValues.put(MediaStore.Images.Media.DATE_ADDED, time / 1000)
|
||||
return localContentValues
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将视频保存到系统图库
|
||||
*
|
||||
* @param videoPath
|
||||
* @param context
|
||||
*/
|
||||
private fun saveVideoQ(videoPath: String, context: Context): Boolean {
|
||||
return try {
|
||||
val contentResolver = context.contentResolver
|
||||
val contentValues =
|
||||
getVideoContentValues(File(videoPath))
|
||||
val localUri = contentResolver.insert(
|
||||
MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
|
||||
contentValues
|
||||
)
|
||||
// 拷贝到指定uri,如果没有这步操作,android11不会在相册显示
|
||||
val out = context.contentResolver.openOutputStream(localUri!!)
|
||||
copyFile(videoPath, out)
|
||||
context.sendBroadcast(Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, localUri))
|
||||
//将该文件扫描到相册
|
||||
//MediaScannerConnection.scanFile(context, new String[] { videoFile }, null, null);
|
||||
true
|
||||
} catch (e: java.lang.Exception) {
|
||||
e.printStackTrace()
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
private fun saveVideo(videoPath: String, context: Context): Boolean {
|
||||
return try {
|
||||
val path = getSavePath() + File.separator + File(videoPath).name
|
||||
val newFile = File(path)
|
||||
if (!newFile!!.parentFile.exists()) {
|
||||
newFile!!.parentFile.mkdirs()
|
||||
}
|
||||
val out = newFile.outputStream()
|
||||
copyFile(videoPath, out)
|
||||
|
||||
val uri = Uri.fromFile(newFile)
|
||||
context.sendBroadcast(Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri))
|
||||
out.close()
|
||||
true
|
||||
} catch (e: java.lang.Exception) {
|
||||
e.printStackTrace()
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun getVideoContentValues(paramFile: File): ContentValues {
|
||||
val time = System.currentTimeMillis()
|
||||
val localContentValues = ContentValues()
|
||||
localContentValues.put(MediaStore.Images.Media.TITLE, paramFile.name)
|
||||
localContentValues.put(MediaStore.Images.Media.DISPLAY_NAME, paramFile.name)
|
||||
localContentValues.put(MediaStore.Images.Media.MIME_TYPE, "video/mp4")
|
||||
localContentValues.put(MediaStore.Images.Media.RELATIVE_PATH, getSavePath())
|
||||
// localContentValues.put(MediaStore.Images.Media.DATE_MODIFIED, time / 1000)
|
||||
// localContentValues.put(MediaStore.Images.Media.DATE_ADDED, time / 1000)
|
||||
return localContentValues
|
||||
}
|
||||
|
||||
/**
|
||||
* 拷贝文件
|
||||
* @param oldPath
|
||||
* @param out
|
||||
* @return
|
||||
*/
|
||||
private fun copyFile(oldPath: String, out: OutputStream?): Boolean {
|
||||
try {
|
||||
var bytesum = 0
|
||||
var byteread = 0
|
||||
val oldFile = File(oldPath)
|
||||
if (oldFile.exists()) {
|
||||
// 读入原文件
|
||||
val inStream: InputStream = FileInputStream(oldPath)
|
||||
val buffer = ByteArray(1444)
|
||||
while (inStream.read(buffer).also { byteread = it } != -1) {
|
||||
bytesum += byteread //字节数 文件大小
|
||||
println(bytesum)
|
||||
out!!.write(buffer, 0, byteread)
|
||||
}
|
||||
inStream.close()
|
||||
out!!.close()
|
||||
return true
|
||||
} else {
|
||||
}
|
||||
} catch (e: java.lang.Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,104 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper.utils
|
||||
|
||||
import android.Manifest
|
||||
import android.app.Activity
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Environment
|
||||
import android.os.PowerManager
|
||||
import android.provider.Settings
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import pub.devrel.easypermissions.EasyPermissions
|
||||
|
||||
|
||||
object PermissionUtil {
|
||||
const val REQUEST_CODE_PERMISSION_STORAGE = 12
|
||||
const val REQUEST_CODE_PERMISSION_NOTIFICATION = 14
|
||||
|
||||
fun hasStoragePermission(context: Context): Boolean {
|
||||
return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
|
||||
val perms = arrayOf(
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||
)
|
||||
EasyPermissions.hasPermissions(context, *perms)
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 30以上区分权限
|
||||
* @param ctx
|
||||
*/
|
||||
fun requestStoragePermission(ctx: Activity) {
|
||||
val perms = arrayOf(
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||
)
|
||||
EasyPermissions.requestPermissions(
|
||||
ctx,
|
||||
"PinkWallpaper need permission",
|
||||
REQUEST_CODE_PERMISSION_STORAGE,
|
||||
*perms
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* android 30 以上管理全文件权限
|
||||
* 是否有权限
|
||||
* @param ctx
|
||||
* @return
|
||||
*/
|
||||
@RequiresApi(api = Build.VERSION_CODES.R)
|
||||
private fun hasFileMangePermission(ctx: Context): Boolean {
|
||||
return Environment.isExternalStorageManager()
|
||||
}
|
||||
|
||||
fun hasAlertWindowPermission(context: Context): Boolean {
|
||||
return Build.VERSION.SDK_INT < Build.VERSION_CODES.M
|
||||
|| Settings.canDrawOverlays(context)
|
||||
}
|
||||
|
||||
fun requestAlertWindowPermission(context: Context) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
|
||||
&& !Settings.canDrawOverlays(context)) {
|
||||
val intent = Intent(
|
||||
Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
|
||||
Uri.parse("package:" + context.packageName)
|
||||
)
|
||||
context.startActivity(intent)
|
||||
}
|
||||
}
|
||||
|
||||
fun hasIgnoringBatteryOptimizations(context: Context): Boolean {
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
var isIgnoring = false
|
||||
val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager?
|
||||
if (powerManager != null) {
|
||||
isIgnoring = powerManager.isIgnoringBatteryOptimizations(context.packageName)
|
||||
}
|
||||
isIgnoring
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
fun requestIgnoreBatteryOptimizations(context: Context) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
try {
|
||||
val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
|
||||
intent.setData(Uri.parse("package:" + context.packageName))
|
||||
context.startActivity(intent)
|
||||
} catch (e: java.lang.Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper.utils
|
||||
|
||||
import android.graphics.drawable.Drawable
|
||||
import androidx.appcompat.content.res.AppCompatResources
|
||||
import com.cute.girl.hd.pink.img.wallpaper.MyApp
|
||||
|
||||
object ResourceUtil {
|
||||
fun getString(resId: Int): String {
|
||||
return MyApp.app.getString(resId)
|
||||
}
|
||||
|
||||
fun getString(resId: Int, vararg args: Any?): String {
|
||||
return String.format(MyApp.app.getString(resId), args)
|
||||
}
|
||||
|
||||
fun getString(str: String, vararg args: Any?): String {
|
||||
return String.format(str, args)
|
||||
}
|
||||
|
||||
fun getColor(colorId: Int): Int {
|
||||
return MyApp.app.resources.getColor(colorId)
|
||||
}
|
||||
|
||||
fun getDrawable(drawableId: Int): Drawable? {
|
||||
var drawable: Drawable? = null
|
||||
try {
|
||||
drawable = AppCompatResources.getDrawable(MyApp.app, drawableId)
|
||||
} catch (e: Exception) {
|
||||
}
|
||||
return drawable
|
||||
}
|
||||
|
||||
fun getStringArray(arrayId: Int): Array<String> {
|
||||
return MyApp.app.resources.getStringArray(arrayId)
|
||||
}
|
||||
|
||||
fun dp2Px(dp: Int): Int {
|
||||
val scale: Float = MyApp.app.resources.displayMetrics.density
|
||||
return (dp * scale + 0.5f).toInt()
|
||||
}
|
||||
|
||||
fun dp2Px(dp: Float): Float {
|
||||
val scale: Float = MyApp.app.resources.displayMetrics.density
|
||||
return dp * scale + 0.5f
|
||||
}
|
||||
|
||||
fun dimens2Px(id: Int): Int {
|
||||
return MyApp.app.resources.getDimensionPixelSize(id)
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,297 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper.utils.des;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Created on 2022/3/2 10:29
|
||||
*
|
||||
* @author Gong Youqiang
|
||||
*/
|
||||
public class Base64 {
|
||||
private static final char[] CA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();
|
||||
private static final int[] IA = new int[256];
|
||||
static {
|
||||
Arrays.fill(IA, -1);
|
||||
for (int i = 0, iS = CA.length; i < iS; i++)
|
||||
IA[CA[i]] = i;
|
||||
IA['='] = 0;
|
||||
}
|
||||
private static final byte[] encodingTable = { (byte) 'A', (byte) 'B',
|
||||
(byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F', (byte) 'G',
|
||||
(byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K', (byte) 'L',
|
||||
(byte) 'M', (byte) 'N', (byte) 'O', (byte) 'P', (byte) 'Q',
|
||||
(byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U', (byte) 'V',
|
||||
(byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z', (byte) 'a',
|
||||
(byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f',
|
||||
(byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j', (byte) 'k',
|
||||
(byte) 'l', (byte) 'm', (byte) 'n', (byte) 'o', (byte) 'p',
|
||||
(byte) 'q', (byte) 'r', (byte) 's', (byte) 't', (byte) 'u',
|
||||
(byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y', (byte) 'z',
|
||||
(byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4',
|
||||
(byte) '5', (byte) '6', (byte) '7', (byte) '8', (byte) '9',
|
||||
(byte) '+', (byte) '/' };
|
||||
private static final byte[] decodingTable;
|
||||
static {
|
||||
decodingTable = new byte[128];
|
||||
for (int i = 0; i < 128; i++) {
|
||||
decodingTable[i] = (byte) -1;
|
||||
}
|
||||
for (int i = 'A'; i <= 'Z'; i++) {
|
||||
decodingTable[i] = (byte) (i - 'A');
|
||||
}
|
||||
for (int i = 'a'; i <= 'z'; i++) {
|
||||
decodingTable[i] = (byte) (i - 'a' + 26);
|
||||
}
|
||||
for (int i = '0'; i <= '9'; i++) {
|
||||
decodingTable[i] = (byte) (i - '0' + 52);
|
||||
}
|
||||
decodingTable['+'] = 62;
|
||||
decodingTable['/'] = 63;
|
||||
}
|
||||
|
||||
public static byte[] encode(byte[] data) {
|
||||
byte[] bytes;
|
||||
int modulus = data.length % 3;
|
||||
if (modulus == 0) {
|
||||
bytes = new byte[(4 * data.length) / 3];
|
||||
} else {
|
||||
bytes = new byte[4 * ((data.length / 3) + 1)];
|
||||
}
|
||||
int dataLength = (data.length - modulus);
|
||||
int a1;
|
||||
int a2;
|
||||
int a3;
|
||||
for (int i = 0, j = 0; i < dataLength; i += 3, j += 4) {
|
||||
a1 = data[i] & 0xff;
|
||||
a2 = data[i + 1] & 0xff;
|
||||
a3 = data[i + 2] & 0xff;
|
||||
bytes[j] = encodingTable[(a1 >>> 2) & 0x3f];
|
||||
bytes[j + 1] = encodingTable[((a1 << 4) | (a2 >>> 4)) & 0x3f];
|
||||
bytes[j + 2] = encodingTable[((a2 << 2) | (a3 >>> 6)) & 0x3f];
|
||||
bytes[j + 3] = encodingTable[a3 & 0x3f];
|
||||
}
|
||||
int b1;
|
||||
int b2;
|
||||
int b3;
|
||||
int d1;
|
||||
int d2;
|
||||
switch (modulus) {
|
||||
case 0: /* nothing left to do */
|
||||
break;
|
||||
case 1:
|
||||
d1 = data[data.length - 1] & 0xff;
|
||||
b1 = (d1 >>> 2) & 0x3f;
|
||||
b2 = (d1 << 4) & 0x3f;
|
||||
bytes[bytes.length - 4] = encodingTable[b1];
|
||||
bytes[bytes.length - 3] = encodingTable[b2];
|
||||
bytes[bytes.length - 2] = (byte) '=';
|
||||
bytes[bytes.length - 1] = (byte) '=';
|
||||
break;
|
||||
case 2:
|
||||
d1 = data[data.length - 2] & 0xff;
|
||||
d2 = data[data.length - 1] & 0xff;
|
||||
b1 = (d1 >>> 2) & 0x3f;
|
||||
b2 = ((d1 << 4) | (d2 >>> 4)) & 0x3f;
|
||||
b3 = (d2 << 2) & 0x3f;
|
||||
bytes[bytes.length - 4] = encodingTable[b1];
|
||||
bytes[bytes.length - 3] = encodingTable[b2];
|
||||
bytes[bytes.length - 2] = encodingTable[b3];
|
||||
bytes[bytes.length - 1] = (byte) '=';
|
||||
break;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static byte[] decode(byte[] data) {
|
||||
byte[] bytes;
|
||||
byte b1;
|
||||
byte b2;
|
||||
byte b3;
|
||||
byte b4;
|
||||
data = discardNonBase64Bytes(data);
|
||||
if (data[data.length - 2] == '=') {
|
||||
bytes = new byte[(((data.length / 4) - 1) * 3) + 1];
|
||||
} else if (data[data.length - 1] == '=') {
|
||||
bytes = new byte[(((data.length / 4) - 1) * 3) + 2];
|
||||
} else {
|
||||
bytes = new byte[((data.length / 4) * 3)];
|
||||
}
|
||||
for (int i = 0, j = 0; i < (data.length - 4); i += 4, j += 3) {
|
||||
b1 = decodingTable[data[i]];
|
||||
b2 = decodingTable[data[i + 1]];
|
||||
b3 = decodingTable[data[i + 2]];
|
||||
b4 = decodingTable[data[i + 3]];
|
||||
bytes[j] = (byte) ((b1 << 2) | (b2 >> 4));
|
||||
bytes[j + 1] = (byte) ((b2 << 4) | (b3 >> 2));
|
||||
bytes[j + 2] = (byte) ((b3 << 6) | b4);
|
||||
}
|
||||
if (data[data.length - 2] == '=') {
|
||||
b1 = decodingTable[data[data.length - 4]];
|
||||
b2 = decodingTable[data[data.length - 3]];
|
||||
bytes[bytes.length - 1] = (byte) ((b1 << 2) | (b2 >> 4));
|
||||
} else if (data[data.length - 1] == '=') {
|
||||
b1 = decodingTable[data[data.length - 4]];
|
||||
b2 = decodingTable[data[data.length - 3]];
|
||||
b3 = decodingTable[data[data.length - 2]];
|
||||
bytes[bytes.length - 2] = (byte) ((b1 << 2) | (b2 >> 4));
|
||||
bytes[bytes.length - 1] = (byte) ((b2 << 4) | (b3 >> 2));
|
||||
} else {
|
||||
b1 = decodingTable[data[data.length - 4]];
|
||||
b2 = decodingTable[data[data.length - 3]];
|
||||
b3 = decodingTable[data[data.length - 2]];
|
||||
b4 = decodingTable[data[data.length - 1]];
|
||||
bytes[bytes.length - 3] = (byte) ((b1 << 2) | (b2 >> 4));
|
||||
bytes[bytes.length - 2] = (byte) ((b2 << 4) | (b3 >> 2));
|
||||
bytes[bytes.length - 1] = (byte) ((b3 << 6) | b4);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static byte[] decode(String data) {
|
||||
byte[] bytes;
|
||||
byte b1;
|
||||
byte b2;
|
||||
byte b3;
|
||||
byte b4;
|
||||
data = discardNonBase64Chars(data);
|
||||
if (data.charAt(data.length() - 2) == '=') {
|
||||
bytes = new byte[(((data.length() / 4) - 1) * 3) + 1];
|
||||
} else if (data.charAt(data.length() - 1) == '=') {
|
||||
bytes = new byte[(((data.length() / 4) - 1) * 3) + 2];
|
||||
} else {
|
||||
bytes = new byte[((data.length() / 4) * 3)];
|
||||
}
|
||||
for (int i = 0, j = 0; i < (data.length() - 4); i += 4, j += 3) {
|
||||
b1 = decodingTable[data.charAt(i)];
|
||||
b2 = decodingTable[data.charAt(i + 1)];
|
||||
b3 = decodingTable[data.charAt(i + 2)];
|
||||
b4 = decodingTable[data.charAt(i + 3)];
|
||||
bytes[j] = (byte) ((b1 << 2) | (b2 >> 4));
|
||||
bytes[j + 1] = (byte) ((b2 << 4) | (b3 >> 2));
|
||||
bytes[j + 2] = (byte) ((b3 << 6) | b4);
|
||||
}
|
||||
if (data.charAt(data.length() - 2) == '=') {
|
||||
b1 = decodingTable[data.charAt(data.length() - 4)];
|
||||
b2 = decodingTable[data.charAt(data.length() - 3)];
|
||||
bytes[bytes.length - 1] = (byte) ((b1 << 2) | (b2 >> 4));
|
||||
} else if (data.charAt(data.length() - 1) == '=') {
|
||||
b1 = decodingTable[data.charAt(data.length() - 4)];
|
||||
b2 = decodingTable[data.charAt(data.length() - 3)];
|
||||
b3 = decodingTable[data.charAt(data.length() - 2)];
|
||||
bytes[bytes.length - 2] = (byte) ((b1 << 2) | (b2 >> 4));
|
||||
bytes[bytes.length - 1] = (byte) ((b2 << 4) | (b3 >> 2));
|
||||
} else {
|
||||
b1 = decodingTable[data.charAt(data.length() - 4)];
|
||||
b2 = decodingTable[data.charAt(data.length() - 3)];
|
||||
b3 = decodingTable[data.charAt(data.length() - 2)];
|
||||
b4 = decodingTable[data.charAt(data.length() - 1)];
|
||||
bytes[bytes.length - 3] = (byte) ((b1 << 2) | (b2 >> 4));
|
||||
bytes[bytes.length - 2] = (byte) ((b2 << 4) | (b3 >> 2));
|
||||
bytes[bytes.length - 1] = (byte) ((b3 << 6) | b4);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
private static byte[] discardNonBase64Bytes(byte[] data) {
|
||||
byte[] temp = new byte[data.length];
|
||||
int bytesCopied = 0;
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
if (isValidBase64Byte(data[i])) {
|
||||
temp[bytesCopied++] = data[i];
|
||||
}
|
||||
}
|
||||
byte[] newData = new byte[bytesCopied];
|
||||
System.arraycopy(temp, 0, newData, 0, bytesCopied);
|
||||
return newData;
|
||||
}
|
||||
|
||||
private static String discardNonBase64Chars(String data) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
int length = data.length();
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (isValidBase64Byte((byte) (data.charAt(i)))) {
|
||||
sb.append(data.charAt(i));
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static boolean isValidBase64Byte(byte b) {
|
||||
if (b == '=') {
|
||||
return true;
|
||||
} else if ((b < 0) || (b >= 128)) {
|
||||
return false;
|
||||
} else if (decodingTable[b] == -1) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Encodes a raw byte array into a BASE64 <code>String</code> representation i accordance with RFC 2045.
|
||||
* @param sArr The bytes to convert. If <code>null</code> or length 0 an empty array will be returned.
|
||||
* @param lineSep Optional "\r\n" after 76 characters, unless end of file.<br>
|
||||
* No line separator will be in breach of RFC 2045 which specifies max 76 per line but will be a
|
||||
* little faster.
|
||||
* @return A BASE64 encoded array. Never <code>null</code>.
|
||||
*/
|
||||
public final static String encodeToString(byte[] sArr, boolean lineSep)
|
||||
{
|
||||
// Reuse char[] since we can't create a String incrementally anyway and StringBuffer/Builder would be slower.
|
||||
return new String(encodeToChar(sArr, lineSep));
|
||||
}
|
||||
|
||||
/** Encodes a raw byte array into a BASE64 <code>char[]</code> representation i accordance with RFC 2045.
|
||||
* @param sArr The bytes to convert. If <code>null</code> or length 0 an empty array will be returned.
|
||||
* @param lineSep Optional "\r\n" after 76 characters, unless end of file.<br>
|
||||
* No line separator will be in breach of RFC 2045 which specifies max 76 per line but will be a
|
||||
* little faster.
|
||||
* @return A BASE64 encoded array. Never <code>null</code>.
|
||||
*/
|
||||
public final static char[] encodeToChar(byte[] sArr, boolean lineSep)
|
||||
{
|
||||
// Check special case
|
||||
int sLen = sArr != null ? sArr.length : 0;
|
||||
if (sLen == 0)
|
||||
return new char[0];
|
||||
|
||||
int eLen = (sLen / 3) * 3; // Length of even 24-bits.
|
||||
int cCnt = ((sLen - 1) / 3 + 1) << 2; // Returned character count
|
||||
int dLen = cCnt + (lineSep ? (cCnt - 1) / 76 << 1 : 0); // Length of returned array
|
||||
char[] dArr = new char[dLen];
|
||||
|
||||
// Encode even 24-bits
|
||||
for (int s = 0, d = 0, cc = 0; s < eLen;) {
|
||||
// Copy next three bytes into lower 24 bits of int, paying attension to sign.
|
||||
int i = (sArr[s++] & 0xff) << 16 | (sArr[s++] & 0xff) << 8 | (sArr[s++] & 0xff);
|
||||
|
||||
// Encode the int into four chars
|
||||
dArr[d++] = CA[(i >>> 18) & 0x3f];
|
||||
dArr[d++] = CA[(i >>> 12) & 0x3f];
|
||||
dArr[d++] = CA[(i >>> 6) & 0x3f];
|
||||
dArr[d++] = CA[i & 0x3f];
|
||||
|
||||
// Add optional line separator
|
||||
if (lineSep && ++cc == 19 && d < dLen - 2) {
|
||||
dArr[d++] = '\r';
|
||||
dArr[d++] = '\n';
|
||||
cc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Pad and encode last bits if source isn't even 24 bits.
|
||||
int left = sLen - eLen; // 0 - 2.
|
||||
if (left > 0) {
|
||||
// Prepare the int
|
||||
int i = ((sArr[eLen] & 0xff) << 10) | (left == 2 ? ((sArr[sLen - 1] & 0xff) << 2) : 0);
|
||||
|
||||
// Set last four chars
|
||||
dArr[dLen - 4] = CA[i >> 12];
|
||||
dArr[dLen - 3] = CA[(i >>> 6) & 0x3f];
|
||||
dArr[dLen - 2] = left == 2 ? CA[i & 0x3f] : '=';
|
||||
dArr[dLen - 1] = '=';
|
||||
}
|
||||
return dArr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,122 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper.utils.des;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.DESKeySpec;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
|
||||
/**
|
||||
* Created on 2022/3/2 10:01
|
||||
*
|
||||
* @author Gong Youqiang
|
||||
*/
|
||||
public class DES {
|
||||
/** 加密KEY */
|
||||
private static final byte[] KEY = "7;9Ku7;:84VG*B78".getBytes();
|
||||
/** 算法 */
|
||||
private static final String ALGORITHM = "DES";
|
||||
/** IV */
|
||||
private static final byte[] IV = "sHjrydLq".getBytes();
|
||||
/** TRANSFORMATION */
|
||||
private static final String TRANSFORMATION = "DES/CBC/PKCS5Padding";
|
||||
|
||||
private static int code = 0;
|
||||
|
||||
public DES() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
* @param code 加密方式:0-“ISO-8859-1”编码,1-base64编码,其它-默认编码(utf-8)
|
||||
*/
|
||||
public DES(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将字符串进行DES加密
|
||||
* @param source 未加密源字符串
|
||||
* @return 加密后字符串
|
||||
*/
|
||||
public static String encrypt(String source) {
|
||||
byte[] retByte = null;
|
||||
|
||||
// Create SecretKey object
|
||||
DESKeySpec dks = null;
|
||||
try {
|
||||
dks = new DESKeySpec(KEY);
|
||||
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
|
||||
SecretKey securekey = keyFactory.generateSecret(dks);
|
||||
|
||||
// Create IvParameterSpec object with initialization vector
|
||||
IvParameterSpec spec = new IvParameterSpec(IV);
|
||||
|
||||
// Create Cipter object
|
||||
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
|
||||
|
||||
// Initialize Cipher object
|
||||
cipher.init(Cipher.ENCRYPT_MODE, securekey, spec);
|
||||
|
||||
// Decrypting data
|
||||
retByte = cipher.doFinal(source.getBytes());
|
||||
|
||||
String result = "";
|
||||
if (code == 0) {
|
||||
result = new String(retByte, "ISO-8859-1");
|
||||
} else if (code == 1) {
|
||||
result = Base64.encodeToString(retByte,false);
|
||||
} else {
|
||||
result = new String(retByte);
|
||||
}
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 将DES加密的字符串解密
|
||||
* @param encrypted 加密过的字符串
|
||||
* @return 未加密源字符串
|
||||
*/
|
||||
public static String decrypt(String encrypted) {
|
||||
byte[] retByte = null;
|
||||
|
||||
// Create SecretKey object
|
||||
DESKeySpec dks = null;
|
||||
try {
|
||||
dks = new DESKeySpec(KEY);
|
||||
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
|
||||
SecretKey securekey = keyFactory.generateSecret(dks);
|
||||
|
||||
// Create IvParameterSpec object with initialization vector
|
||||
IvParameterSpec spec = new IvParameterSpec(IV);
|
||||
|
||||
// Create Cipter object
|
||||
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
|
||||
|
||||
// Initialize Cipher object
|
||||
cipher.init(Cipher.DECRYPT_MODE, securekey, spec);
|
||||
|
||||
if (code == 0) {
|
||||
retByte = encrypted.getBytes("ISO-8859-1");
|
||||
} else if (code == 1) {
|
||||
retByte = Base64.decode(encrypted);
|
||||
} else {
|
||||
retByte = encrypted.getBytes();
|
||||
}
|
||||
|
||||
// Decrypting data
|
||||
retByte = cipher.doFinal(retByte);
|
||||
return new String(retByte, "utf-8");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,18 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper.utils.des;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class DesUtil {
|
||||
public static void main(String[] args) {
|
||||
List<String> list = new ArrayList();
|
||||
for (String str : list) {
|
||||
String ss = DES.encrypt(str);
|
||||
System.out.println("<" + ss + ">");
|
||||
String aa = DES.decrypt(ss);
|
||||
System.out.println(">" + aa + "<");
|
||||
System.out.println("---------------------");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,96 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper.view
|
||||
|
||||
|
||||
import android.graphics.Rect
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.recyclerview.widget.StaggeredGridLayoutManager
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.GlobalExt.dp2PxInt
|
||||
class CustomItemDecoration : RecyclerView.ItemDecoration {
|
||||
|
||||
// item的水平、垂直方向的间距
|
||||
private var verticalSpacing = 0
|
||||
private var horizontalSpacing = 0
|
||||
|
||||
// recyclerview 左右分别额外的边距,可正可负,效果如|◼ ◼ ◼ ◼|、| ◼ ◼ ◼ ◼ |
|
||||
//首尾margin是 spacing + extraSpacing
|
||||
private var extraSpacing = 0
|
||||
|
||||
// item占满一行时,该item是否需要左右间距
|
||||
var needVerticalSpacingInSingleLine = true
|
||||
var needHorizontalSpacingInSingleLine = true
|
||||
|
||||
constructor(spacing: Int) {
|
||||
initSpacing(spacing, spacing, 0)
|
||||
}
|
||||
|
||||
constructor(spacing: Int, extraSpacing: Int) {
|
||||
initSpacing(spacing, spacing, extraSpacing)
|
||||
}
|
||||
|
||||
constructor(verticalSpacing: Int, horizontalSpacing: Int, extraSpacing: Int) {
|
||||
initSpacing(verticalSpacing, horizontalSpacing, extraSpacing)
|
||||
}
|
||||
|
||||
private fun initSpacing(verticalSpacing: Int, horizontalSpacing: Int, extraSpacing: Int) {
|
||||
this.horizontalSpacing = horizontalSpacing.dp2PxInt()
|
||||
this.verticalSpacing = verticalSpacing.dp2PxInt()
|
||||
this.extraSpacing = extraSpacing.dp2PxInt()
|
||||
}
|
||||
|
||||
override fun getItemOffsets(
|
||||
outRect: Rect,
|
||||
view: View,
|
||||
parent: RecyclerView,
|
||||
state: RecyclerView.State
|
||||
) {
|
||||
val position = parent.getChildAdapterPosition(view)
|
||||
var spanCount = 1
|
||||
var spanSize = 1
|
||||
var spanIndex = 0
|
||||
|
||||
parent.layoutManager?.run {
|
||||
when (this) {
|
||||
is StaggeredGridLayoutManager -> {
|
||||
spanCount = this.spanCount
|
||||
(view.layoutParams as StaggeredGridLayoutManager.LayoutParams)?.run {
|
||||
if (isFullSpan) spanSize = spanCount
|
||||
spanIndex = this.spanIndex
|
||||
}
|
||||
}
|
||||
|
||||
is GridLayoutManager -> {
|
||||
spanCount = this.spanCount
|
||||
spanSize = this.spanSizeLookup.getSpanSize(position)
|
||||
spanIndex = (view.layoutParams as GridLayoutManager.LayoutParams).spanIndex
|
||||
}
|
||||
|
||||
is LinearLayoutManager -> {
|
||||
outRect.left = verticalSpacing
|
||||
outRect.right = verticalSpacing
|
||||
outRect.bottom = horizontalSpacing
|
||||
return
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
if (spanSize == spanCount) {
|
||||
outRect.left =
|
||||
if (needVerticalSpacingInSingleLine) verticalSpacing + extraSpacing else 0
|
||||
outRect.right =
|
||||
if (needVerticalSpacingInSingleLine) verticalSpacing + extraSpacing else 0
|
||||
outRect.bottom = if (needHorizontalSpacingInSingleLine) horizontalSpacing else 0
|
||||
} else {
|
||||
val itemAllSpacing = (verticalSpacing * (spanCount + 1) + extraSpacing * 2) / spanCount
|
||||
val left = verticalSpacing * (spanIndex + 1) - itemAllSpacing * spanIndex + extraSpacing
|
||||
val right = itemAllSpacing - left
|
||||
outRect.left = left
|
||||
outRect.right = right
|
||||
outRect.bottom = horizontalSpacing
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,58 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper.view
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import com.cute.girl.hd.pink.img.wallpaper.R
|
||||
import com.cute.girl.hd.pink.img.wallpaper.databinding.DialogSetBinding
|
||||
import com.cute.girl.hd.pink.img.wallpaper.utils.DeviceUtil
|
||||
|
||||
class SetAsDialog(private val ctx: Context, init: SetAsDialog.() -> Unit) :
|
||||
Dialog(ctx, R.style.AppDialog) {
|
||||
|
||||
private lateinit var binding: DialogSetBinding
|
||||
var onClickHomeScreen: (() -> Unit)? = null
|
||||
var onClickLockScreen: (() -> Unit)? = null
|
||||
var onClickBoth: (() -> Unit)? = null
|
||||
|
||||
init {
|
||||
init()
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = DialogSetBinding.inflate(LayoutInflater.from(ctx))
|
||||
setContentView(binding.root)
|
||||
initViews()
|
||||
}
|
||||
|
||||
private fun initViews() {
|
||||
//设置宽度
|
||||
val p = window!!.attributes
|
||||
p.width = (DeviceUtil.getScreenWidth(ctx) * 0.8).toInt() //设置dialog的宽度为当前手机屏幕的宽度*0.8
|
||||
window!!.attributes = p
|
||||
|
||||
setCancelable(true)
|
||||
setCanceledOnTouchOutside(true)
|
||||
|
||||
binding.ivClose.setOnClickListener {
|
||||
dismiss()
|
||||
}
|
||||
|
||||
binding.llHomeScreen.setOnClickListener {
|
||||
dismiss()
|
||||
onClickHomeScreen?.invoke()
|
||||
}
|
||||
|
||||
binding.llLockScreen.setOnClickListener {
|
||||
dismiss()
|
||||
onClickLockScreen?.invoke()
|
||||
}
|
||||
|
||||
binding.llBoth.setOnClickListener {
|
||||
dismiss()
|
||||
onClickBoth?.invoke()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper.view
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.widget.FrameLayout
|
||||
|
||||
class SquareFrameLayout : FrameLayout {
|
||||
constructor(context: Context) : super(context)
|
||||
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
|
||||
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
|
||||
context,
|
||||
attrs,
|
||||
defStyleAttr
|
||||
)
|
||||
|
||||
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
||||
super.onMeasure(widthMeasureSpec, widthMeasureSpec)
|
||||
}
|
||||
}
|
||||
6
app/src/main/res/drawable/d_card_dialog_24dp.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="#DDF0EF" />
|
||||
<corners android:radius="24dp" />
|
||||
</shape>
|
||||
6
app/src/main/res/drawable/d_card_theme_pink_32dp.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="@color/theme_pink"/>
|
||||
<corners android:radius="32dp"/>
|
||||
</shape>
|
||||
12
app/src/main/res/drawable/ic_back.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="20dp"
|
||||
android:height="16dp"
|
||||
android:viewportWidth="20"
|
||||
android:viewportHeight="16">
|
||||
<path
|
||||
android:pathData="M10.061,1.04C10.646,1.626 10.646,2.575 10.061,3.161L6.722,6.5L17,6.5C17.828,6.5 18.5,7.172 18.5,8C18.5,8.828 17.828,9.5 17,9.5L6.722,9.5L10.061,12.839C10.646,13.425 10.646,14.374 10.061,14.96C9.475,15.546 8.525,15.546 7.939,14.96L2.04,9.061C1.454,8.475 1.454,7.525 2.04,6.939L7.939,1.04C8.525,0.454 9.475,0.454 10.061,1.04Z"
|
||||
android:strokeWidth="1"
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="evenOdd"
|
||||
android:strokeColor="#00000000"/>
|
||||
</vector>
|
||||
20
app/src/main/res/drawable/ic_close.xml
Normal file
@ -0,0 +1,20 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M12,12m-12,0a12,12 0,1 1,24 0a12,12 0,1 1,-24 0"
|
||||
android:strokeAlpha="0.15923418"
|
||||
android:strokeWidth="1"
|
||||
android:fillColor="#1C211F"
|
||||
android:fillType="evenOdd"
|
||||
android:strokeColor="#00000000"
|
||||
android:fillAlpha="0.15923418"/>
|
||||
<path
|
||||
android:pathData="M17,8.4l-1.4,-1.4l-3.6,3.6l-3.6,-3.6l-1.4,1.4l3.6,3.6l-3.6,3.6l1.4,1.4l3.6,-3.6l3.6,3.6l1.4,-1.4l-3.6,-3.6z"
|
||||
android:strokeWidth="1"
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="evenOdd"
|
||||
android:strokeColor="#00000000"/>
|
||||
</vector>
|
||||
9
app/src/main/res/drawable/ic_download.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="144dp"
|
||||
android:height="144dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:pathData="M441.1,354.7l20,-186.8c2.7,-25.6 24.7,-45 50.9,-45 26.2,0 48.2,19.4 50.9,45l20,186.8a61.4,61.4 0,0 0,61.1 54.9h85.4c15.6,0 28.3,13.1 28.3,29.2 0,7.5 -2.8,14.7 -7.8,20.1L542.8,682.7a41.7,41.7 0,0 1,-61.6 0L274.1,458.9a29.8,29.8 0,0 1,1 -41.2c5.3,-5.2 12.3,-8 19.6,-8h85.4a61.4,61.4 0,0 0,61.1 -54.9zM214.7,654.1l23.3,93.1a41,41 0,0 0,39.7 31H746.3a41,41 0,0 0,39.7 -31l23.3,-93.1A52.5,52.5 0,0 1,860.2 614.4a41,41 0,0 1,41 41v143.4a102.4,102.4 0,0 1,-102.4 102.4H225.3a102.4,102.4 0,0 1,-102.4 -102.4V655.4a41,41 0,0 1,41 -41c24.1,0 45.1,16.4 50.9,39.7z"
|
||||
android:fillColor="#ffffff"/>
|
||||
</vector>
|
||||
74
app/src/main/res/drawable/ic_launcher_background.xml
Normal file
@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector
|
||||
android:height="108dp"
|
||||
android:width="108dp"
|
||||
android:viewportHeight="108"
|
||||
android:viewportWidth="108"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#3DDC84"
|
||||
android:pathData="M0,0h108v108h-108z"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M9,0L9,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M19,0L19,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M29,0L29,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M39,0L39,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M49,0L49,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M59,0L59,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M69,0L69,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M79,0L79,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M89,0L89,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M99,0L99,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,9L108,9"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,19L108,19"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,29L108,29"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,39L108,39"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,49L108,49"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,59L108,59"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,69L108,69"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,79L108,79"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,89L108,89"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,99L108,99"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M19,29L89,29"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M19,39L89,39"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M19,49L89,49"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M19,59L89,59"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M19,69L89,69"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M19,79L89,79"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M29,19L29,89"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M39,19L39,89"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M49,19L49,89"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M59,19L59,89"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M69,19L69,89"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M79,19L79,89"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
</vector>
|
||||
30
app/src/main/res/drawable/ic_launcher_foreground.xml
Normal file
@ -0,0 +1,30 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:endX="85.84757"
|
||||
android:endY="92.4963"
|
||||
android:startX="42.9492"
|
||||
android:startY="49.59793"
|
||||
android:type="linear">
|
||||
<item
|
||||
android:color="#44000000"
|
||||
android:offset="0.0" />
|
||||
<item
|
||||
android:color="#00000000"
|
||||
android:offset="1.0" />
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="nonZero"
|
||||
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
||||
android:strokeWidth="1"
|
||||
android:strokeColor="#00000000" />
|
||||
</vector>
|
||||
12
app/src/main/res/drawable/ic_menu.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="20dp"
|
||||
android:height="16dp"
|
||||
android:viewportWidth="20"
|
||||
android:viewportHeight="16">
|
||||
<path
|
||||
android:pathData="M3,1.5L17,1.5C17.828,1.5 18.5,2.172 18.5,3C18.5,3.828 17.828,4.5 17,4.5L3,4.5C2.172,4.5 1.5,3.828 1.5,3C1.5,2.172 2.172,1.5 3,1.5ZM3,6.5L17,6.5C17.828,6.5 18.5,7.172 18.5,8C18.5,8.828 17.828,9.5 17,9.5L3,9.5C2.172,9.5 1.5,8.828 1.5,8C1.5,7.172 2.172,6.5 3,6.5ZM3,11.5L17,11.5C17.828,11.5 18.5,12.172 18.5,13C18.5,13.828 17.828,14.5 17,14.5L3,14.5C2.172,14.5 1.5,13.828 1.5,13C1.5,12.172 2.172,11.5 3,11.5Z"
|
||||
android:strokeWidth="1"
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="evenOdd"
|
||||
android:strokeColor="#00000000"/>
|
||||
</vector>
|
||||
12
app/src/main/res/drawable/ic_placeholder.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="144dp"
|
||||
android:height="144dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:pathData="M810.6,1024H213.4A211.2,211.2 0,0 1,0 810.6V213.4A211.2,211.2 0,0 1,213.4 0h597.3A211.2,211.2 0,0 1,1024 213.4v597.3A211.2,211.2 0,0 1,810.6 1024zM213.4,85.4c-68.3,0 -128,59.7 -128,128v597.3c0,68.3 59.7,128 128,128h597.3c68.3,0 128,-59.7 128,-128V213.4c0,-68.3 -59.7,-128 -128,-128H213.4z"
|
||||
android:fillColor="@color/theme_pink"/>
|
||||
<path
|
||||
android:pathData="M0,768L768,0h-119.4L0,648.6v119.4zM955.7,51.2L51.2,955.7c17,25.6 42.6,42.6 68.2,51.2L1006.9,119.5c-17.1,-25.6 -34.2,-42.6 -51.2,-68.2zM460.8,1024L1024,460.8V341.4L341.4,1024H460.8z"
|
||||
android:fillColor="@color/theme_pink"/>
|
||||
</vector>
|
||||
9
app/src/main/res/drawable/ic_wallpaper.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="144dp"
|
||||
android:height="144dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:pathData="M245.3,128C180.9,128 128,180.9 128,245.3v21.3a32,32 0,1 0,64 0v-21.3C192,215.5 215.5,192 245.3,192h21.3a32,32 0,1 0,0 -64h-21.3zM373.3,128a32,32 0,1 0,0 64h85.3a32,32 0,1 0,0 -64h-85.3zM565.3,128a32,32 0,1 0,0 64h85.3a32,32 0,1 0,0 -64h-85.3zM757.3,128a32,32 0,1 0,0 64h21.3c29.8,0 53.3,23.5 53.3,53.3v21.3a32,32 0,1 0,64 0v-21.3C896,180.9 843.1,128 778.7,128h-21.3zM650.7,277.3c-29.3,0 -55.4,12.2 -71.9,30.7C562.2,326.7 554.7,350.2 554.7,373.3c0,23.1 7.6,46.7 24.1,65.3C595.3,457.2 621.3,469.3 650.7,469.3s55.4,-12.2 71.9,-30.7C739.1,420 746.7,396.4 746.7,373.3c0,-23.1 -7.6,-46.7 -24.1,-65.3C706,289.5 680,277.3 650.7,277.3zM159.5,340.9A32,32 0,0 0,128 373.3v85.3a32,32 0,1 0,64 0v-85.3a32,32 0,0 0,-32.5 -32.4zM863.5,340.9A32,32 0,0 0,832 373.3v85.3a32,32 0,1 0,64 0v-85.3a32,32 0,0 0,-32.5 -32.4zM650.7,341.3c13.3,0 19.3,3.8 24.1,9.3 4.8,5.4 7.9,13.9 7.9,22.7 0,8.9 -3.1,17.3 -7.9,22.7 -4.8,5.4 -10.8,9.3 -24.1,9.3s-19.3,-3.8 -24.1,-9.3c-4.8,-5.4 -7.9,-13.9 -7.9,-22.7 0,-8.9 3.1,-17.3 7.9,-22.7 4.8,-5.4 10.8,-9.3 24.1,-9.3zM512,512.1a86,86 0,0 0,-60 24.1L192.9,786.9C192.4,784.2 192,781.5 192,778.7v-21.3a32,32 0,0 0,-32.5 -32.4A32,32 0,0 0,128 757.3v21.3c0,64.4 52.9,117.3 117.3,117.3h21.3a32,32 0,1 0,0 -64h-21.3c-2.2,0 -4.3,-0.4 -6.4,-0.6l257.6,-249.2a21.9,21.9 0,0 1,31.1 0L785.1,831.4c-2.1,0.2 -4.2,0.6 -6.4,0.6h-21.3a32,32 0,1 0,0 64h21.3c64.4,0 117.3,-52.9 117.3,-117.3v-21.3a32,32 0,0 0,-32.5 -32.4A32,32 0,0 0,832 757.3v21.3c0,2.8 -0.4,5.5 -0.9,8.3L572.1,536.2A86.1,86.1 0,0 0,512 512.1zM159.5,532.9A32,32 0,0 0,128 565.3v85.3a32,32 0,1 0,64 0v-85.3a32,32 0,0 0,-32.5 -32.4zM863.5,532.9A32,32 0,0 0,832 565.3v85.3a32,32 0,1 0,64 0v-85.3a32,32 0,0 0,-32.5 -32.4zM373.3,832a32,32 0,1 0,0 64h85.3a32,32 0,1 0,0 -64h-85.3zM565.3,832a32,32 0,1 0,0 64h85.3a32,32 0,1 0,0 -64h-85.3z"
|
||||
android:fillColor="#ffffff"/>
|
||||
</vector>
|
||||
BIN
app/src/main/res/font/fredoka.ttf
Normal file
83
app/src/main/res/layout/ability_category.xml
Normal file
@ -0,0 +1,83 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp">
|
||||
|
||||
<View
|
||||
android:id="@+id/vCover"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/theme_pink" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivBack"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_gravity="start"
|
||||
android:layout_marginStart="21dp"
|
||||
android:padding="3dp"
|
||||
android:src="@drawable/ic_back" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:fontFamily="@font/fredoka"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="24sp"
|
||||
tools:text="@string/app_name" />
|
||||
</RelativeLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<!-- <com.scwang.smart.refresh.layout.SmartRefreshLayout-->
|
||||
<!-- android:id="@+id/refreshLayout"-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="match_parent">-->
|
||||
|
||||
<!-- <com.scwang.smart.refresh.header.ClassicsHeader-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="wrap_content" />-->
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvEmpty"
|
||||
android:layout_width="300dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:fontFamily="@font/fredoka"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:text="@string/empty_data_txt"
|
||||
android:textColor="@color/theme_gray"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rv"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<!-- <com.scwang.smart.refresh.footer.ClassicsFooter-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="wrap_content" />-->
|
||||
|
||||
|
||||
<!-- </com.scwang.smart.refresh.layout.SmartRefreshLayout>-->
|
||||
</FrameLayout>
|
||||
|
||||
</LinearLayout>
|
||||
143
app/src/main/res/layout/ability_main.xml
Normal file
@ -0,0 +1,143 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tl="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/drawer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/theme_white"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/theme_white"
|
||||
android:orientation="vertical">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp"
|
||||
android:background="@color/theme_pink">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivMenu"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginStart="16dp"
|
||||
android:src="@drawable/ic_menu" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginStart="52dp"
|
||||
android:fontFamily="@font/fredoka"
|
||||
android:text="@string/app_name"
|
||||
android:textColor="@color/theme_white"
|
||||
android:textSize="24sp" />
|
||||
</RelativeLayout>
|
||||
|
||||
<com.flyco.tablayout.SlidingTabLayout
|
||||
android:id="@+id/stl_tab"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:background="@color/theme_pink"
|
||||
app:tl_indicator_color="@color/white"
|
||||
app:tl_indicator_corner_radius="1.5dp"
|
||||
app:tl_indicator_height="3dp"
|
||||
app:tl_indicator_width="20dp"
|
||||
app:tl_textBold="BOTH"
|
||||
app:tl_textSelectColor="@color/theme_white"
|
||||
app:tl_textUnselectColor="@color/theme_gray"
|
||||
app:tl_textsize="18sp" />
|
||||
|
||||
<androidx.viewpager.widget.ViewPager
|
||||
android:id="@+id/viewPager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="start"
|
||||
android:background="@color/theme_pink"
|
||||
android:orientation="vertical"
|
||||
android:visibility="visible">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/rlRate"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="52dp"
|
||||
android:layout_marginTop="24dp"
|
||||
android:paddingHorizontal="16dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:fontFamily="@font/fredoka"
|
||||
android:gravity="center"
|
||||
android:text="@string/rate_us"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16sp" />
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/rlShare"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="52dp"
|
||||
android:paddingHorizontal="16dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:fontFamily="@font/fredoka"
|
||||
android:gravity="center"
|
||||
android:text="@string/share_app"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16sp" />
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/rlPrivacy"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="52dp"
|
||||
android:paddingHorizontal="16dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:fontFamily="@font/fredoka"
|
||||
android:gravity="center"
|
||||
android:text="@string/privacy_policy"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16sp" />
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="52dp"
|
||||
android:paddingHorizontal="16dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvVersion"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:fontFamily="@font/fredoka"
|
||||
android:gravity="center"
|
||||
android:textColor="@color/theme_gray"
|
||||
android:textSize="16sp"
|
||||
tools:text="v1.0.1" />
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</androidx.drawerlayout.widget.DrawerLayout>
|
||||
116
app/src/main/res/layout/ability_preview.xml
Normal file
@ -0,0 +1,116 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginBottom="4dp">
|
||||
|
||||
<androidx.viewpager2.widget.ViewPager2
|
||||
android:id="@+id/view_pager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/rlBottom"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|center_horizontal"
|
||||
android:layout_marginBottom="32dp"
|
||||
android:background="@drawable/d_card_theme_pink_32dp"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:visibility="visible">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/tvSet"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:elevation="1dp"
|
||||
android:gravity="center"
|
||||
android:padding="8dp"
|
||||
android:src="@drawable/ic_wallpaper"
|
||||
android:visibility="visible" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/tvDownload"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginStart="40dp"
|
||||
android:elevation="1dp"
|
||||
android:gravity="center"
|
||||
android:padding="8dp"
|
||||
android:src="@drawable/ic_download"
|
||||
android:visibility="visible" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp">
|
||||
|
||||
<View
|
||||
android:id="@+id/vCover"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:alpha="0.45"
|
||||
android:background="@color/theme_pink" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivBack"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_gravity="start|center_vertical"
|
||||
android:layout_marginStart="12dp"
|
||||
android:padding="3dp"
|
||||
android:src="@drawable/ic_back"
|
||||
android:visibility="visible" />
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/flDownload"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="gone"
|
||||
android:gravity="center">
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:alpha="0.5"
|
||||
android:background="@color/white" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/fredoka"
|
||||
android:gravity="center"
|
||||
android:text="@string/downloading_image"
|
||||
android:textColor="@color/theme_pink"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/pbb"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="16dp"
|
||||
android:indeterminateTint="@color/theme_pink" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</FrameLayout>
|
||||
39
app/src/main/res/layout/ability_privacy.xml
Normal file
@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp"
|
||||
android:background="@color/theme_pink">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivBack"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_gravity="start"
|
||||
android:layout_marginStart="21dp"
|
||||
android:padding="3dp"
|
||||
android:src="@drawable/ic_back"
|
||||
android:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:fontFamily="@font/fredoka"
|
||||
android:text="@string/privacy_policy"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="24sp" />
|
||||
</RelativeLayout>
|
||||
|
||||
<WebView
|
||||
android:id="@+id/web_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</LinearLayout>
|
||||
33
app/src/main/res/layout/ability_start.xml
Normal file
@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="120dp"
|
||||
android:layout_height="120dp"
|
||||
android:src="@mipmap/logo" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="15dp"
|
||||
android:text="@string/app_name"
|
||||
android:textColor="@color/theme_pink"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<ProgressBar
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:indeterminateTint="@color/theme_pink" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</FrameLayout>
|
||||
111
app/src/main/res/layout/dialog_set.xml
Normal file
@ -0,0 +1,111 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/d_card_dialog_24dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="18dp"
|
||||
android:fontFamily="@font/fredoka"
|
||||
android:gravity="center"
|
||||
android:minWidth="300dp"
|
||||
android:text="@string/set_wallpaper"
|
||||
android:textColor="@color/theme_pink"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/llHomeScreen"
|
||||
android:layout_width="220dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="16dp"
|
||||
android:background="@drawable/d_card_theme_pink_32dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingHorizontal="24dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_weight="1"
|
||||
android:fontFamily="@font/fredoka"
|
||||
android:gravity="center"
|
||||
android:text="@string/home_screen"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/llLockScreen"
|
||||
android:layout_width="220dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="16dp"
|
||||
android:background="@drawable/d_card_theme_pink_32dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingHorizontal="24dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_weight="1"
|
||||
android:fontFamily="@font/fredoka"
|
||||
android:gravity="center"
|
||||
android:text="@string/lock_screen"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/llBoth"
|
||||
android:layout_width="220dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginBottom="30dp"
|
||||
android:background="@drawable/d_card_theme_pink_32dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingHorizontal="24dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:fontFamily="@font/fredoka"
|
||||
android:gravity="center"
|
||||
android:text="@string/both"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivClose"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_gravity="end"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:padding="4dp"
|
||||
android:src="@drawable/ic_close" />
|
||||
|
||||
</FrameLayout>
|
||||
56
app/src/main/res/layout/item_category.xml
Normal file
@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout 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"
|
||||
tools:ignore="MissingDefaultResource">
|
||||
|
||||
<com.cute.girl.hd.pink.img.wallpaper.view.SquareFrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/theme_gray"
|
||||
app:cardCornerRadius="6dp"
|
||||
app:cardElevation="0dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivPlaceholder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginHorizontal="24dp"
|
||||
android:src="@drawable/ic_placeholder" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivWallpaper"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:scaleType="centerCrop" />
|
||||
|
||||
<View
|
||||
android:id="@+id/vCover"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:alpha="0.45"
|
||||
android:background="@color/black" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginStart="16dp"
|
||||
android:fontFamily="@font/fredoka"
|
||||
android:text="@string/app_name"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="18sp" />
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
</com.cute.girl.hd.pink.img.wallpaper.view.SquareFrameLayout>
|
||||
|
||||
</FrameLayout>
|
||||
25
app/src/main/res/layout/item_image.xml
Normal file
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout 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="174dp"
|
||||
android:background="@color/theme_gray"
|
||||
tools:ignore="MissingDefaultResource">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivPlaceholder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginHorizontal="24dp"
|
||||
android:src="@drawable/ic_placeholder" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivWallpaper"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:scaleType="centerCrop" />
|
||||
|
||||
</FrameLayout>
|
||||
25
app/src/main/res/layout/item_preview.xml
Normal file
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout 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="match_parent"
|
||||
android:background="@color/theme_gray"
|
||||
tools:ignore="MissingDefaultResource">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivPlaceholder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginHorizontal="24dp"
|
||||
android:src="@drawable/ic_placeholder" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivWallpaper"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:scaleType="centerCrop" />
|
||||
|
||||
</FrameLayout>
|
||||
6
app/src/main/res/layout/page_category.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
46
app/src/main/res/layout/page_recent.xml
Normal file
@ -0,0 +1,46 @@
|
||||
<?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:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/theme_white">
|
||||
|
||||
<!-- <com.scwang.smart.refresh.layout.SmartRefreshLayout-->
|
||||
<!-- android:id="@+id/refreshLayout"-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="match_parent">-->
|
||||
|
||||
<!-- <com.scwang.smart.refresh.header.ClassicsHeader-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="wrap_content" />-->
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvEmpty"
|
||||
android:layout_width="300dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:fontFamily="@font/fredoka"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:text="@string/empty_data_txt"
|
||||
android:textColor="@color/theme_gray"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rv"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<!-- <com.scwang.smart.refresh.footer.ClassicsFooter-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="wrap_content" />-->
|
||||
|
||||
|
||||
<!-- </com.scwang.smart.refresh.layout.SmartRefreshLayout>-->
|
||||
|
||||
</FrameLayout>
|
||||
5
app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background"/>
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||
</adaptive-icon>
|
||||
5
app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background"/>
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||
</adaptive-icon>
|
||||
BIN
app/src/main/res/mipmap-hdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 5.9 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp
Normal file
|
After Width: | Height: | Size: 6.8 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 6.0 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 8.5 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 9.7 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/logo.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
9
app/src/main/res/values/colors.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="black">#FF000000</color>
|
||||
<color name="white">#FFFFFFFF</color>
|
||||
|
||||
<color name="theme_white">#EBF6F5</color>
|
||||
<color name="theme_pink">#ED99B2</color>
|
||||
<color name="theme_gray">#D8D8D8</color>
|
||||
</resources>
|
||||
17
app/src/main/res/values/strings.xml
Normal file
@ -0,0 +1,17 @@
|
||||
<resources>
|
||||
<string name="app_name">Art Wallpaper</string>
|
||||
<string name="empty_data_txt">Image loading failed, please pull down to refresh and reload.</string>
|
||||
<string name="downloading_image">Downloading HD Image...</string>
|
||||
<string name="set_wallpaper">Set Wallpaper</string>
|
||||
<string name="set_success">Wallpaper set successfully</string>
|
||||
<string name="home_screen">Home Screen</string>
|
||||
<string name="lock_screen">Lock Screen</string>
|
||||
<string name="both">Both</string>
|
||||
<string name="download_failed">Wallpaper download failed!</string>
|
||||
<string name="privacy_policy">Privacy Policy</string>
|
||||
<string name="share_app">Share App</string>
|
||||
<string name="share_text">Share Girl Wallpaper with your friends! share the link %s</string>
|
||||
<string name="rate_us">Rate Us</string>
|
||||
<string name="saved_to_album">Saved to album</string>
|
||||
<string name="save_failed">Save failed</string>
|
||||
</resources>
|
||||
12
app/src/main/res/values/styles.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<style name="AppDialog" parent="@android:style/Theme.Dialog">
|
||||
<item name="android:windowFrame">@null</item>
|
||||
<item name="android:windowIsFloating">true</item>
|
||||
<item name="android:windowIsTranslucent">true</item>
|
||||
<item name="android:windowNoTitle">true</item>
|
||||
<item name="android:background">@android:color/transparent</item>
|
||||
<item name="android:windowBackground">@android:color/transparent</item>
|
||||
<item name="android:backgroundDimEnabled">true</item>
|
||||
</style>
|
||||
</resources>
|
||||
16
app/src/main/res/values/themes.xml
Normal file
@ -0,0 +1,16 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
<style name="Theme.PinkWallpaper" parent="Theme.MaterialComponents.DayNight.NoActionBar">
|
||||
<!-- Primary brand color. -->
|
||||
<item name="colorPrimary">@color/theme_pink</item>
|
||||
<item name="colorPrimaryVariant">@color/theme_gray</item>
|
||||
<item name="colorOnPrimary">@color/white</item>
|
||||
<!-- Secondary brand color. -->
|
||||
<item name="colorSecondary">@color/theme_pink</item>
|
||||
<item name="colorSecondaryVariant">@color/theme_gray</item>
|
||||
<item name="colorOnSecondary">@color/black</item>
|
||||
<!-- Status bar color. -->
|
||||
<item name="android:statusBarColor">?attr/colorPrimaryVariant</item>
|
||||
<!-- Customize your theme here. -->
|
||||
</style>
|
||||
</resources>
|
||||
13
app/src/main/res/xml/backup_rules.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
Sample backup rules file; uncomment and customize as necessary.
|
||||
See https://developer.android.com/guide/topics/data/autobackup
|
||||
for details.
|
||||
Note: This file is ignored for devices older that API 31
|
||||
See https://developer.android.com/about/versions/12/backup-restore
|
||||
-->
|
||||
<full-backup-content>
|
||||
<!--
|
||||
<include domain="sharedpref" path="."/>
|
||||
<exclude domain="sharedpref" path="device.xml"/>
|
||||
-->
|
||||
</full-backup-content>
|
||||
19
app/src/main/res/xml/data_extraction_rules.xml
Normal file
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
Sample data extraction rules file; uncomment and customize as necessary.
|
||||
See https://developer.android.com/about/versions/12/backup-restore#xml-changes
|
||||
for details.
|
||||
-->
|
||||
<data-extraction-rules>
|
||||
<cloud-backup>
|
||||
<!-- TODO: Use <include> and <exclude> to control what is backed up.
|
||||
<include .../>
|
||||
<exclude .../>
|
||||
-->
|
||||
</cloud-backup>
|
||||
<!--
|
||||
<device-transfer>
|
||||
<include .../>
|
||||
<exclude .../>
|
||||
</device-transfer>
|
||||
-->
|
||||
</data-extraction-rules>
|
||||
19
app/src/main/res/xml/network_security_config.xml
Normal file
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<network-security-config>
|
||||
|
||||
<!-- For AdColony, this permits all cleartext traffic: -->
|
||||
<base-config cleartextTrafficPermitted="true">
|
||||
<trust-anchors>
|
||||
<certificates src="system" />
|
||||
</trust-anchors>
|
||||
</base-config>
|
||||
<!-- End AdColony section -->
|
||||
|
||||
<domain-config cleartextTrafficPermitted="true">
|
||||
|
||||
<!-- For Meta Audience Network, this permits cleartext traffic to localhost: -->
|
||||
<domain includeSubdomains="true">127.0.0.1</domain>
|
||||
<!-- End Meta Audience Network section -->
|
||||
|
||||
</domain-config>
|
||||
</network-security-config>
|
||||
@ -0,0 +1,17 @@
|
||||
package com.cute.girl.hd.pink.img.wallpaper
|
||||
|
||||
import org.junit.Test
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
class ExampleUnitTest {
|
||||
@Test
|
||||
fun addition_isCorrect() {
|
||||
assertEquals(4, 2 + 2)
|
||||
}
|
||||
}
|
||||
BIN
app/testArtWallpaper.jks
Normal file
12
build.gradle.kts
Normal file
@ -0,0 +1,12 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
plugins {
|
||||
alias(libs.plugins.androidApplication) apply false
|
||||
alias(libs.plugins.jetbrainsKotlinAndroid) apply false
|
||||
id("com.google.gms.google-services") version "4.3.15" apply false
|
||||
id ("com.google.firebase.crashlytics") version "2.9.2" apply false
|
||||
}
|
||||
buildscript{
|
||||
dependencies{
|
||||
classpath("com.applovin.quality:AppLovinQualityServiceGradlePlugin:+")
|
||||
}
|
||||
}
|
||||
24
gradle.properties
Normal file
@ -0,0 +1,24 @@
|
||||
# Project-wide Gradle settings.
|
||||
# IDE (e.g. Android Studio) users:
|
||||
# Gradle settings configured through the IDE *will override*
|
||||
# any settings specified in this file.
|
||||
# For more details on how to configure your build environment visit
|
||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. For more details, visit
|
||||
# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
|
||||
# org.gradle.parallel=true
|
||||
# AndroidX package structure to make it clearer which packages are bundled with the
|
||||
# Android operating system, and which are packaged with your app's APK
|
||||
# https://developer.android.com/topic/libraries/support-library/androidx-rn
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
# Kotlin code style for this project: "official" or "obsolete":
|
||||
kotlin.code.style=official
|
||||
# Enables namespacing of each library's R class so that its R class includes only the
|
||||
# resources declared in the library itself and none from the library's dependencies,
|
||||
# thereby reducing the size of the R class for that library
|
||||
android.nonTransitiveRClass=true
|
||||
22
gradle/libs.versions.toml
Normal file
@ -0,0 +1,22 @@
|
||||
[versions]
|
||||
agp = "8.1.3"
|
||||
kotlin = "1.9.0"
|
||||
coreKtx = "1.13.1"
|
||||
junit = "4.13.2"
|
||||
junitVersion = "1.1.5"
|
||||
espressoCore = "3.5.1"
|
||||
appcompat = "1.6.1"
|
||||
material = "1.12.0"
|
||||
|
||||
[libraries]
|
||||
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
||||
junit = { group = "junit", name = "junit", version.ref = "junit" }
|
||||
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
|
||||
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
|
||||
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
|
||||
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
|
||||
|
||||
[plugins]
|
||||
androidApplication = { id = "com.android.application", version.ref = "agp" }
|
||||
jetbrainsKotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
|
||||
|
||||