This commit is contained in:
litingting 2024-07-04 10:11:47 +08:00
commit 151c7ceea8
106 changed files with 7949 additions and 0 deletions

15
.gitignore vendored Normal file
View 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
View File

@ -0,0 +1 @@
/build

BIN
app/ArtWallpaper.jks Normal file

Binary file not shown.

93
app/build.gradle.kts Normal file
View 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
View 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
View 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

View File

@ -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)
}
}

View 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>

File diff suppressed because it is too large Load Diff

View 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)
}
}

View File

@ -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
}
}
}

View File

@ -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
}
}
}

View File

@ -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
}
}
}

View File

@ -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
}
}
}

View File

@ -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
}
}
}

View File

@ -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

View File

@ -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()
}

View File

@ -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
}
}

View File

@ -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"
}
}

View File

@ -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 ""
}
}

View File

@ -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"
}
}

View File

@ -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"
}

View File

@ -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()
}

View File

@ -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( );
}

View File

@ -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);
}
});
}
}

View File

@ -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)
}
}

View File

@ -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)
}
}
}

View File

@ -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) {
}
}
}

View File

@ -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)
}
}
}

View File

@ -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)
}
}
}

View File

@ -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)
}
}
}

View File

@ -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) {
}
}
}

View File

@ -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()
}
}
}

View File

@ -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)
}
}
}

View File

@ -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()
}
}
}

View File

@ -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
}
}

View File

@ -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()
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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()
}
}
}
}

View File

@ -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)
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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("---------------------");
}
}
}

View File

@ -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
}
}
}

View File

@ -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()
}
}
}

View File

@ -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)
}
}

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

Binary file not shown.

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View File

@ -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

Binary file not shown.

12
build.gradle.kts Normal file
View 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
View 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
View 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" }

Some files were not shown because too many files have changed in this diff Show More