Initial commit

This commit is contained in:
Kevin Alberts 2024-12-27 01:17:26 +01:00 committed by GitHub
commit 2a6c87df54
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
41 changed files with 1398 additions and 0 deletions

1
sample/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/build

49
sample/build.gradle.kts Normal file
View file

@ -0,0 +1,49 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
}
android {
namespace = "tv.projectivy.plugin.wallpaperprovider.sample"
compileSdk = 35
defaultConfig {
applicationId = "tv.projectivy.plugin.wallpaperprovider.sample"
minSdk = 23
targetSdk = 35
versionCode = 1
versionName = "1.01"
}
buildTypes {
release {
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlin {
compilerOptions {
jvmTarget.set(JvmTarget.JVM_17)
}
}
}
dependencies {
implementation("androidx.core:core-ktx:1.13.1")
implementation("androidx.leanback:leanback:1.2.0-alpha04")
implementation("androidx.appcompat:appcompat:1.7.0")
implementation("com.google.android.material:material:1.12.0")
implementation("androidx.preference:preference-ktx:1.2.1")
implementation("com.google.code.gson:gson:2.11.0")
implementation(project(":api"))
}

21
sample/proguard-rules.pro vendored Normal file
View file

@ -0,0 +1,21 @@
# 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

View file

@ -0,0 +1,82 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:ignore="MissingLeanbackLauncher">
<uses-permission android:name="android.permission.INTERNET" />
<uses-feature
android:name="android.hardware.touchscreen"
android:required="false" />
<uses-feature
android:name="android.software.leanback"
android:required="true" />
<application
android:allowBackup="true"
android:label="@string/plugin_name"
android:supportsRtl="true"
android:icon="@mipmap/ic_launcher"
android:banner="@mipmap/ic_banner"
android:theme="@style/Theme.ProjectivyWallpaperProvider">
<activity
android:name=".SettingsActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".WallpaperProviderService"
android:exported="true"
android:label="@string/plugin_name"
android:icon="@mipmap/ic_launcher"
android:banner="@mipmap/ic_banner"
tools:ignore="ExportedService">
<!-- Mandatory for the plugin to be detected, DO NOT CHANGE -->
<intent-filter>
<action android:name="tv.projectivy.plugin.WALLPAPER_PROVIDER"/>
</intent-filter>
<!-- Api version this plugin is compatible with -->
<meta-data
android:name="apiVersion"
android:value="1"/>
<!--Plugin UUID *** YOU NEED TO CHANGE IT *** -->
<!--https://www.uuidgenerator.net/version4 -->
<meta-data
android:name="uuid"
android:value="@string/plugin_uuid"/>
<!-- Plugin name -->
<meta-data
android:name="name"
android:value="@string/plugin_name"/>
<!-- Plugin activity called by Projectivy to configure it -->
<meta-data
android:name="settingsActivity"
android:value=".SettingsActivity"/>
<!-- How long should Projectivy keep wallpapers before a new request -->
<meta-data
android:name="itemsCacheDurationMillis"
android:value="@integer/items_cache_duration_millis"/>
<!-- This sample plugin will receive time_elapsed and launcher_idle_mode_changed events -->
<meta-data
android:name="updateMode"
android:value="17"/>
</service>
</application>
</manifest>

View file

@ -0,0 +1,86 @@
package tv.projectivy.plugin.wallpaperprovider.sample
import android.content.Context
import android.content.SharedPreferences
import androidx.preference.PreferenceManager
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.ToNumberPolicy
import com.google.gson.reflect.TypeToken
object PreferencesManager {
private const val IMAGE_URL_KEY = "image_url_key"
lateinit var preferences: SharedPreferences
fun init(context: Context) {
preferences = PreferenceManager.getDefaultSharedPreferences(context)
}
private inline fun SharedPreferences.edit(operation: (SharedPreferences.Editor) -> Unit) {
val editor = this.edit()
operation(editor)
editor.apply()
}
operator fun set(key: String, value: Any?) =
when (value) {
is String? -> preferences.edit { it.putString(key, value) }
is Int -> preferences.edit { it.putInt(key, value) }
is Boolean -> preferences.edit { it.putBoolean(key, value) }
is Float -> preferences.edit { it.putFloat(key, value) }
is Long -> preferences.edit { it.putLong(key, value) }
else -> throw UnsupportedOperationException("Not yet implemented")
}
inline operator fun <reified T : Any> get(
key: String,
defaultValue: T? = null
): T =
when (T::class) {
String::class -> preferences.getString(key, defaultValue as String? ?: "") as T
Int::class -> preferences.getInt(key, defaultValue as? Int ?: -1) as T
Boolean::class -> preferences.getBoolean(key, defaultValue as? Boolean ?: false) as T
Float::class -> preferences.getFloat(key, defaultValue as? Float ?: -1f) as T
Long::class -> preferences.getLong(key, defaultValue as? Long ?: -1) as T
else -> throw UnsupportedOperationException("Not yet implemented")
}
var imageUrl: String
get() = PreferencesManager[IMAGE_URL_KEY, "https://images.pexels.com/photos/462162/pexels-photo-462162.jpeg"]
set(value) { PreferencesManager[IMAGE_URL_KEY]=value }
fun export(): String {
return Gson().toJson(preferences.all)
}
fun import(prefs: String): Boolean {
val gson = GsonBuilder()
.setObjectToNumberStrategy(ToNumberPolicy.LONG_OR_DOUBLE)
.create()
try {
val type = object : TypeToken<Map<String, Any>>() {}.type
val map = gson.fromJson<Map<String, Any>>(prefs, type)
val editor = preferences.edit()
editor.clear()
map.forEach { (key: String, value: Any) ->
when(value) {
is Boolean -> editor.putBoolean(key, value)
is Double -> editor.putFloat(key, value.toFloat())
is Float -> editor.putFloat(key, value)
is Int -> editor.putInt(key, value)
is Long -> editor.putInt(key, value.toInt())
is String -> editor.putString(key, value)
is ArrayList<*> -> editor.putStringSet(key, java.util.HashSet(value as java.util.ArrayList<String>))
is Set<*> -> editor.putStringSet(key, value as Set<String>)
}
}
editor.apply()
} catch (ex: Exception) {
ex.printStackTrace()
return false
}
return true
}
}

View file

@ -0,0 +1,17 @@
package tv.projectivy.plugin.wallpaperprovider.sample
import android.os.Bundle
import androidx.fragment.app.FragmentActivity
import androidx.leanback.app.GuidedStepSupportFragment
class SettingsActivity : FragmentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val fragment: GuidedStepSupportFragment = SettingsFragment()
if (savedInstanceState == null) {
GuidedStepSupportFragment.addAsRoot(this, fragment, android.R.id.content)
}
}
}

View file

@ -0,0 +1,50 @@
package tv.projectivy.plugin.wallpaperprovider.sample
import android.os.Bundle
import android.util.Log
import androidx.appcompat.content.res.AppCompatResources
import androidx.leanback.app.GuidedStepSupportFragment
import androidx.leanback.widget.GuidanceStylist.Guidance
import androidx.leanback.widget.GuidedAction
import kotlin.CharSequence
class SettingsFragment : GuidedStepSupportFragment() {
override fun onCreateGuidance(savedInstanceState: Bundle?): Guidance {
return Guidance(
getString(R.string.plugin_name),
getString(R.string.plugin_description),
getString(R.string.settings),
AppCompatResources.getDrawable(requireActivity(), R.drawable.ic_plugin)
)
}
override fun onCreateActions(actions: MutableList<GuidedAction>, savedInstanceState: Bundle?) {
PreferencesManager.init(requireContext())
val currentImageUrl = PreferencesManager.imageUrl
val action = GuidedAction.Builder(context)
.id(ACTION_ID_IMAGE_URL)
.title(R.string.setting_image_url_title)
.description(currentImageUrl)
.editDescription(currentImageUrl)
.descriptionEditable(true)
.build()
actions.add(action)
}
override fun onGuidedActionClicked(action: GuidedAction) {
when (action.id) {
ACTION_ID_IMAGE_URL -> {
val params: CharSequence? = action.editDescription
findActionById(ACTION_ID_IMAGE_URL)?.description = params
notifyActionChanged(findActionPositionById(ACTION_ID_IMAGE_URL))
PreferencesManager.imageUrl = params.toString()
}
}
}
companion object {
private const val ACTION_ID_IMAGE_URL = 1L
}
}

View file

@ -0,0 +1,86 @@
package tv.projectivy.plugin.wallpaperprovider.sample
import android.app.Service
import android.content.ContentResolver
import android.content.Intent
import android.net.Uri
import android.os.IBinder
import tv.projectivy.plugin.wallpaperprovider.api.Event
import tv.projectivy.plugin.wallpaperprovider.api.IWallpaperProviderService
import tv.projectivy.plugin.wallpaperprovider.api.Wallpaper
import tv.projectivy.plugin.wallpaperprovider.api.WallpaperType
class WallpaperProviderService: Service() {
override fun onCreate() {
super.onCreate()
PreferencesManager.init(this)
}
override fun onBind(intent: Intent): IBinder {
// Return the interface.
return binder
}
private val binder = object : IWallpaperProviderService.Stub() {
override fun getWallpapers(event: Event?): List<Wallpaper> {
return when (event) {
is Event.TimeElapsed -> {
// This is where you generate the wallpaper list that will be cycled every x minute
return listOf(
// DRAWABLE can be served from app drawable/
Wallpaper(getDrawableUri(R.drawable.ic_banner_drawable).toString(), WallpaperType.DRAWABLE),
// IMAGE can be served from app drawable/, local storage or internet
Wallpaper(PreferencesManager.imageUrl, WallpaperType.IMAGE, author = "Pixabay"),
// ANIMATED_DRAWABLE can be served from app drawable/
Wallpaper(getDrawableUri(R.drawable.anim_sample).toString(), WallpaperType.ANIMATED_DRAWABLE),
// LOTTIE can be served from app raw/, local storage or internet
Wallpaper(getDrawableUri(R.raw.gradient).toString(), WallpaperType.LOTTIE),
// VIDEO can be served from app raw/, local storage or internet (some formats might not be supported, though)
Wallpaper(getDrawableUri(R.raw.light).toString(), WallpaperType.VIDEO)
)
}
// Below are "dynamic events" that might interest you in special cases
// You will only receive dynamic events depending on the updateMode declared in your manifest
// Don't subscribe if not interested :
// - this will consume device resources unnecessarily
// - some cache optimizations won't be enabled for dynamic wallpaper providers
// When "now playing" changes (ex: a song starts or stops)
is Event.NowPlayingChanged -> emptyList()
// When the focused card changes
is Event.CardFocused -> emptyList()
// When the focused "program" card changes
is Event.ProgramCardFocused -> emptyList()
// When Projectivy enters or exits idle mode
is Event.LauncherIdleModeChanged -> {
return if (event.isIdle) { listOf(Wallpaper(getDrawableUri(R.drawable.ic_plugin).toString(), WallpaperType.DRAWABLE)) }
else emptyList()
}
else -> emptyList() // Returning an empty list won't change the currently displayed wallpaper
}
}
override fun getPreferences(): String {
return PreferencesManager.export()
}
override fun setPreferences(params: String) {
PreferencesManager.import(params)
}
fun getDrawableUri(drawableId: Int): Uri {
return Uri.Builder()
.scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
.authority(resources.getResourcePackageName(drawableId))
.appendPath(resources.getResourceTypeName(drawableId))
.appendPath(resources.getResourceEntryName(drawableId))
.build()
}
}
}

View file

@ -0,0 +1,89 @@
<animated-vector
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt">
<aapt:attr name="android:drawable">
<vector android:height="100dp" android:viewportHeight="1333.3"
android:viewportWidth="1333.3" android:width="100dp">
<group
android:name="group"
android:rotation="0"
android:pivotX="666"
android:pivotY="666"
android:scaleX="1.5"
android:scaleY="1.5"
>
<path android:fillColor="#ccd35933"
android:pathData="M666.7,666.7C807.3,378.3 585.1,156 0,-0L95.2,-0C648.3,173.6 838.7,395.8 666.7,666.7" />
<path android:fillColor="#ccd35933"
android:pathData="m666.7,666.7c201.3,-249.9 42.6,-472.1 -476.2,-666.7l95.2,-0C767.7,218.7 894.7,440.9 666.7,666.7" />
<path android:fillColor="#ccd35933"
android:pathData="m666.7,666.7c251.9,-198.8 156.6,-421 -285.7,-666.7l95.2,-0C875.7,275.1 939.2,497.3 666.7,666.7" />
<path android:fillColor="#ccd35933"
android:pathData="m666.7,666.7c289.8,-137.8 258.1,-360 -95.2,-666.7L666.7,-0c303.4,340 303.4,562.2 0,666.7" />
<path android:fillColor="#ccd35933"
android:pathData="m666.7,666.7c313.2,-69.8 344.9,-292.1 95.2,-666.7l95.2,-0C1049.2,410.1 985.7,632.3 666.7,666.7" />
<path android:fillColor="#ccd35933"
android:pathData="m666.7,666.7c320.9,1.6 416.1,-220.6 285.7,-666.7l95.2,-0C1112.3,482 985.4,704.2 666.7,666.7" />
<path android:fillColor="#ccd35933"
android:pathData="m666.7,666.7c312.5,73 471.2,-149.3 476.2,-666.7l95.2,-0C1159.5,551.9 969,774.2 666.7,666.7" />
<path android:fillColor="#ccd35933"
android:pathData="m666.7,666.7c288.4,140.7 510.6,-81.6 666.7,-666.7L1333.3,95.2C1159.7,648.3 937.5,838.7 666.7,666.7" />
<path android:fillColor="#ccd35933"
android:pathData="M666.7,666.7C916.5,868 1138.8,709.3 1333.3,190.5L1333.3,285.7C1114.7,767.7 892.4,894.7 666.7,666.7" />
<path android:fillColor="#ccd35933"
android:pathData="M666.7,666.7C865.5,918.5 1087.7,823.3 1333.3,381L1333.3,476.2C1058.3,875.7 836,939.2 666.7,666.7" />
<path android:fillColor="#ccd35933"
android:pathData="M666.7,666.7C804.5,956.5 1026.7,924.7 1333.3,571.4L1333.3,666.7C993.4,970.1 771.1,970.1 666.7,666.7" />
<path android:fillColor="#ccd35933"
android:pathData="M666.7,666.7C736.5,979.9 958.7,1011.6 1333.3,761.9L1333.3,857.1C923.2,1049.2 701,985.7 666.7,666.7" />
<path android:fillColor="#ccd35933"
android:pathData="M666.7,666.7C665.1,987.6 887.3,1082.8 1333.3,952.4L1333.3,1047.6C851.4,1112.3 629.1,985.4 666.7,666.7" />
<path android:fillColor="#ccd35933"
android:pathData="M666.7,666.7C593.7,979.1 815.9,1137.9 1333.3,1142.9L1333.3,1238.1C781.4,1159.5 559.2,969 666.7,666.7" />
<path android:fillColor="#ccd35933"
android:pathData="M666.7,666.7C526,955.1 748.2,1177.3 1333.3,1333.3L1238.1,1333.3C685.1,1159.7 494.6,937.5 666.7,666.7" />
<path android:fillColor="#ccd35933"
android:pathData="M666.7,666.7C465.3,916.5 624.1,1138.8 1142.9,1333.3L1047.6,1333.3C565.6,1114.7 438.6,892.4 666.7,666.7" />
<path android:fillColor="#ccd35933"
android:pathData="M666.7,666.7C414.8,865.5 510,1087.7 952.4,1333.3L857.1,1333.3C457.6,1058.3 394.1,836 666.7,666.7" />
<path android:fillColor="#ccd35933"
android:pathData="M666.7,666.7C376.9,804.5 408.6,1026.7 761.9,1333.3L666.7,1333.3c-303.4,-340 -303.4,-562.2 0,-666.7" />
<path android:fillColor="#ccd35933"
android:pathData="M666.7,666.7C353.5,736.5 321.7,958.7 571.4,1333.3L476.2,1333.3C284.1,923.2 347.6,701 666.7,666.7" />
<path android:fillColor="#ccd35933"
android:pathData="M666.7,666.7C345.8,665.1 250.5,887.3 381,1333.3L285.7,1333.3C221,851.4 348,629.1 666.7,666.7" />
<path android:fillColor="#ccd35933"
android:pathData="M666.7,666.7C354.2,593.7 195.5,815.9 190.5,1333.3L95.2,1333.3C173.8,781.4 364.3,559.2 666.7,666.7" />
<path android:fillColor="#ccd35933"
android:pathData="M666.7,666.7C378.3,526 156,748.2 0,1333.3L0,1238.1C173.6,685.1 395.8,494.6 666.7,666.7" />
<path android:fillColor="#ccd35933"
android:pathData="M666.7,666.7C416.8,465.3 194.6,624.1 0,1142.9l0,-95.2C218.7,565.6 440.9,438.6 666.7,666.7" />
<path android:fillColor="#ccd35933"
android:pathData="M666.7,666.7C467.8,414.8 245.6,510 0,952.4l0,-95.2C275.1,457.6 497.3,394.1 666.7,666.7" />
<path android:fillColor="#ccd35933"
android:pathData="M666.7,666.7C528.9,376.9 306.7,408.6 0,761.9L0,666.7c340,-303.4 562.2,-303.4 666.7,-0" />
<path android:fillColor="#ccd35933"
android:pathData="M666.7,666.7C596.8,353.5 374.6,321.7 0,571.4l0,-95.2C410.1,284.1 632.3,347.6 666.7,666.7" />
<path android:fillColor="#ccd35933"
android:pathData="M666.7,666.7C668.3,345.8 446,250.5 0,381l0,-95.2C482,221 704.2,348 666.7,666.7" />
<path android:fillColor="#ccd35933"
android:pathData="M666.7,666.7C739.6,354.2 517.4,195.5 0,190.5l0,-95.2C551.9,173.8 774.2,364.3 666.7,666.7" />
</group>
</vector>
</aapt:attr>
<target android:name="group">
<aapt:attr name="android:animation">
<set>
<objectAnimator
android:startOffset="0"
android:interpolator="@android:anim/linear_interpolator"
android:repeatCount="infinite"
android:duration="10000"
android:propertyName="rotation"
android:valueFrom="0"
android:valueTo="360" />
</set>
</aapt:attr>
</target>
</animated-vector>

View file

@ -0,0 +1,20 @@
<vector android:height="180dp" android:viewportHeight="90"
android:viewportWidth="160" android:width="320dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M66.5,37.8h-0.7c-0.5,0 -0.8,-0.4 -0.8,-0.9c0,-0.2 0.1,-0.4 0.2,-0.6l0.5,-0.5c0.3,-0.3 0.3,-0.8 0,-1.1l-1.2,-1.2c-0.3,-0.3 -0.8,-0.3 -1.1,0l-0.5,0.5c-0.3,0.3 -0.8,0.3 -1.1,0c-0.2,-0.2 -0.2,-0.4 -0.2,-0.6v-0.7c0,-0.4 -0.4,-0.8 -0.8,-0.8l0,0H59c-0.4,0 -0.8,0.4 -0.8,0.8l0,0v0.7c0,0.5 -0.4,0.8 -0.9,0.8c-0.2,0 -0.3,-0.1 -0.5,-0.2l-0.5,-0.5c-0.3,-0.3 -0.8,-0.3 -1.1,0L54,34.7c-0.3,0.3 -0.3,0.8 0,1.1c0,0 0,0 0,0l0.4,0.4c0.4,0.3 0.4,0.9 0,1.3c-0.2,0.2 -0.4,0.3 -0.6,0.3h-0.7c-0.4,0 -0.8,0.4 -0.8,0.8c0,0 0,0 0,0v1.6c0,0.4 0.4,0.8 0.8,0.8c0,0 0,0 0,0h0.7c0.5,0 0.9,0.5 0.8,1c0,0.2 -0.1,0.4 -0.2,0.5L54,43.1c-0.3,0.3 -0.3,0.8 0,1.1c0,0 0,0 0,0l1.2,1.2c0.3,0.3 0.8,0.3 1.1,0c0,0 0,0 0,0l0.5,-0.5c0.4,-0.3 0.9,-0.3 1.2,0.1c0.1,0.1 0.2,0.3 0.2,0.5v0.7c0,0.4 0.3,0.8 0.8,0.9c0,0 0,0 0,0h1.6c0.4,0 0.8,-0.4 0.8,-0.8c0,0 0,0 0,0v-0.7c0,-0.5 0.5,-0.8 0.9,-0.8c0.2,0 0.4,0.1 0.5,0.2l0.5,0.5c0.3,0.3 0.8,0.3 1.1,0c0,0 0,0 0,0l1.2,-1.2c0.3,-0.3 0.3,-0.8 0,-1.1c0,0 0,0 0,0l-0.4,-0.4c-0.4,-0.4 -0.3,-1 0,-1.3c0.2,-0.1 0.4,-0.2 0.6,-0.3h0.7c0.4,0 0.8,-0.4 0.8,-0.8c0,0 0,0 0,0v-1.7C67.3,38.2 66.9,37.8 66.5,37.8zM59.8,42.2c-1.5,0 -2.7,-1.2 -2.7,-2.7c0,-1.5 1.2,-2.7 2.7,-2.7c1.5,0 2.7,1.2 2.7,2.7l0,0C62.5,41 61.3,42.2 59.8,42.2z"/>
<path android:fillColor="@color/projectivy_plugin_color" android:pathData="M73.9,36.4c-0.4,-0.9 -2.4,-1.7 -5.7,-2.3c2.9,4.6 1.6,10.7 -3,13.7c-4.6,2.9 -10.7,1.6 -13.7,-3c-2.4,-3.7 -2,-8.6 1,-11.9c-2.9,-0.1 -6.1,-0.1 -9.7,-0.1c-19.6,0 -30,1.4 -31.1,3.7c0,0 -1.1,2.1 -1,6.8h11.1c0.5,-0.1 0.9,0.2 1,0.7c0,0 0,0.1 0,0.1c0,0.5 -0.6,0.8 -1.2,0.8H10.8c0.1,0.7 0.2,1.5 0.3,2.3h13.1c0.5,-0.1 0.9,0.2 1,0.7c0,0 0,0.1 0,0.1c0,0.5 -0.6,0.8 -1.2,0.8H11.3c0.1,0.8 0.3,1.5 0.4,2.2h14.8c0.5,-0.1 0.9,0.2 1,0.7c0,0 0,0.1 0,0.1c0,0.4 -0.6,0.8 -1.2,0.8H12.1c1.5,5.7 2.9,5.7 2.9,5.7h2v1.2c0,0.6 1.2,1 2.4,1h9.6c1.2,0 2.4,-0.5 2.4,-1v-1.2h22.7v1.2c0,0.6 1.2,1 2.4,1h9.6c1.2,0 2.4,-0.5 2.4,-1v-1.2h2c0,0 2.2,0 4,-10.8C75.8,39.7 73.9,36.4 73.9,36.4z"/>
<path android:fillColor="@color/projectivy_plugin_color" android:pathData="M100,59.9v5h-1V53.1h1v1.5h0c0.3,-0.6 0.7,-1 1.2,-1.3s1.1,-0.4 1.7,-0.4c0.5,0 1,0.1 1.4,0.3s0.7,0.4 1,0.8s0.5,0.8 0.6,1.2s0.2,1 0.2,1.6c0,0.7 -0.1,1.3 -0.2,1.8s-0.4,1 -0.7,1.4s-0.7,0.7 -1.1,0.9s-0.9,0.3 -1.5,0.3C101.4,61.3 100.6,60.8 100,59.9L100,59.9zM100,57.8c0,0.4 0.1,0.7 0.2,1s0.3,0.6 0.5,0.8s0.5,0.4 0.8,0.6s0.7,0.2 1,0.2c0.4,0 0.8,-0.1 1.1,-0.3s0.6,-0.4 0.8,-0.7s0.4,-0.7 0.5,-1.1s0.2,-0.9 0.2,-1.5c0,-0.5 -0.1,-0.9 -0.2,-1.3s-0.3,-0.7 -0.5,-1s-0.5,-0.5 -0.8,-0.6s-0.6,-0.2 -1,-0.2c-0.4,0 -0.8,0.1 -1.1,0.2s-0.6,0.4 -0.9,0.6s-0.4,0.6 -0.5,0.9s-0.2,0.7 -0.2,1.1V57.8z"/>
<path android:fillColor="@color/projectivy_plugin_color" android:pathData="M109.2,61.1V49.3h1v11.8H109.2z"/>
<path android:fillColor="@color/projectivy_plugin_color" android:pathData="M119.7,61.1v-1.4h0c-0.5,1 -1.4,1.5 -2.5,1.5c-1.9,0 -2.9,-1.2 -2.9,-3.5v-4.7h1v4.5c0,1 0.2,1.7 0.5,2.1s0.9,0.7 1.6,0.7c0.3,0 0.7,-0.1 0.9,-0.2s0.5,-0.3 0.7,-0.6s0.4,-0.5 0.5,-0.9s0.2,-0.7 0.2,-1.1v-4.6h1v8H119.7z"/>
<path android:fillColor="@color/projectivy_plugin_color" android:pathData="M130.5,60.5c0,1.5 -0.3,2.6 -1,3.3c-0.7,0.7 -1.7,1.1 -3.1,1.1c-0.9,0 -1.7,-0.2 -2.5,-0.6v-1c0.9,0.5 1.7,0.7 2.5,0.7c2.1,0 3.1,-1.1 3.1,-3.3v-1h0c-0.6,1.1 -1.6,1.6 -2.8,1.6c-0.5,0 -0.9,-0.1 -1.4,-0.3s-0.8,-0.4 -1.1,-0.8s-0.5,-0.8 -0.7,-1.3s-0.2,-1 -0.2,-1.7c0,-0.7 0.1,-1.3 0.3,-1.8s0.4,-1 0.7,-1.4s0.7,-0.7 1.2,-0.9s1,-0.3 1.5,-0.3c1.1,0 2,0.5 2.5,1.4h0v-1.2h1V60.5zM129.5,56.3c0,-0.3 -0.1,-0.6 -0.2,-0.9s-0.3,-0.6 -0.5,-0.8s-0.5,-0.4 -0.8,-0.5c-0.3,-0.1 -0.6,-0.2 -1,-0.2c-0.4,0 -0.8,0.1 -1.1,0.2s-0.6,0.4 -0.9,0.7s-0.4,0.7 -0.5,1.1s-0.2,0.9 -0.2,1.4c0,0.5 0.1,0.9 0.2,1.3s0.3,0.7 0.5,1s0.5,0.5 0.8,0.6s0.7,0.2 1,0.2c0.4,0 0.8,-0.1 1.1,-0.2c0.3,-0.1 0.6,-0.3 0.8,-0.6s0.4,-0.5 0.5,-0.9s0.2,-0.7 0.2,-1.1V56.3z"/>
<path android:fillColor="@color/projectivy_plugin_color" android:pathData="M135,51.1c-0.2,0 -0.4,-0.1 -0.5,-0.2s-0.2,-0.3 -0.2,-0.5c0,-0.2 0.1,-0.4 0.2,-0.5s0.3,-0.2 0.5,-0.2c0.1,0 0.2,0 0.3,0.1s0.2,0.1 0.2,0.1s0.1,0.1 0.2,0.2s0.1,0.2 0.1,0.3c0,0.1 0,0.2 -0.1,0.3s-0.1,0.2 -0.2,0.2s-0.1,0.1 -0.2,0.2S135.1,51.1 135,51.1zM134.5,61.1v-8h1v8H134.5z"/>
<path android:fillColor="@color/projectivy_plugin_color" android:pathData="M144.4,61.1v-4.6c0,-1.8 -0.7,-2.7 -2,-2.7c-0.3,0 -0.7,0.1 -1,0.2s-0.6,0.3 -0.8,0.6s-0.4,0.5 -0.5,0.9s-0.2,0.7 -0.2,1.1v4.6h-1v-8h1v1.4h0c0.6,-1.1 1.5,-1.6 2.7,-1.6c0.9,0 1.5,0.3 2,0.9s0.7,1.4 0.7,2.5v4.9H144.4z"/>
<path android:fillColor="@android:color/white" android:pathData="M80.2,31.2v9.9c0,0.8 -0.2,1.6 -0.5,2.3c-0.3,0.7 -0.7,1.3 -1.3,1.8c-1.1,1.1 -2.6,1.7 -4.1,1.7h-0.1c-0.8,0 -1.5,-0.2 -2.3,-0.5c-0.7,-0.3 -1.4,-0.7 -1.9,-1.3c-0.5,-0.5 -1,-1.2 -1.3,-1.9c-0.3,-0.7 -0.4,-1.5 -0.4,-2.3h3.6c0,0.6 0.2,1.2 0.7,1.7c0.4,0.4 1,0.7 1.7,0.7c0.3,0 0.6,-0.1 0.9,-0.2c0.3,-0.1 0.5,-0.3 0.7,-0.5c0.2,-0.2 0.4,-0.5 0.5,-0.7c0.1,-0.3 0.2,-0.6 0.2,-0.9v-9.8H80.2z"/>
<path android:fillColor="@android:color/white" android:pathData="M91.7,34.9h-6.5v2.4h5.2v3.6h-5.2v2.5h6.5V47H81.6V31.3h10.1V34.9z"/>
<path android:fillColor="@android:color/white" android:pathData="M99.8,47c-1,0 -2,-0.2 -3,-0.6c-1,-0.4 -1.9,-1 -2.6,-1.7c-0.7,-0.7 -1.3,-1.6 -1.7,-2.6c-0.8,-1.9 -0.8,-4.1 0,-6c0.8,-1.9 2.4,-3.5 4.3,-4.3c1.9,-0.8 4,-0.8 5.9,0c1,0.4 1.9,1 2.6,1.7l-2.6,2.5c-0.4,-0.4 -0.9,-0.7 -1.4,-0.9c-0.5,-0.2 -1.1,-0.3 -1.6,-0.3c-0.5,0 -1.1,0.1 -1.6,0.3c-0.5,0.2 -1,0.5 -1.4,0.9c-0.4,0.4 -0.7,0.9 -0.9,1.4c-0.2,0.5 -0.3,1.1 -0.3,1.6c0,0.6 0.1,1.1 0.3,1.6c0.2,0.5 0.5,1 0.9,1.4c0.4,0.4 0.9,0.7 1.4,0.9c0.5,0.2 1,0.3 1.6,0.3c0.6,0 1.1,-0.1 1.6,-0.3c0.5,-0.2 1,-0.5 1.4,-0.9l2.6,2.6c-0.7,0.7 -1.6,1.3 -2.6,1.7C101.8,46.8 100.8,47 99.8,47z"/>
<path android:fillColor="@android:color/white" android:pathData="M115.8,31.2v3.6h-3V47h-3.6V34.9h-3v-3.6H115.8z"/>
<path android:fillColor="@android:color/white" android:pathData="M120.7,47h-3.6V31.2h3.6V47z"/>
<path android:fillColor="@android:color/white" android:pathData="M132,31.2h3.8L130.5,47h-3.4l-5,-15.8h3.8l3,9.7L132,31.2z"/>
<path android:fillColor="@android:color/white" android:pathData="M139.1,47l1.8,-4.4l-5.3,-11.3h4l3.2,6.7l2.8,-6.8h3.9L143,47H139.1z"/>
<path android:fillColor="@android:color/white" android:pathData="M38.4,38.1c0,0.9 -0.2,1.7 -0.5,2.5c-0.6,1.5 -1.9,2.8 -3.4,3.4c-0.8,0.3 -1.6,0.5 -2.5,0.5V47h-3.6V31.6H32c0.9,0 1.7,0.2 2.5,0.6c0.7,0.3 1.4,0.8 2,1.4c0.6,0.6 1,1.3 1.4,2C38.2,36.3 38.4,37.2 38.4,38.1zM32,41c0.4,0 0.8,-0.1 1.1,-0.3c0.3,-0.2 0.6,-0.4 0.9,-0.6c0.3,-0.3 0.5,-0.6 0.6,-0.9c0.1,-0.4 0.2,-0.7 0.2,-1.1c0,-0.4 -0.1,-0.8 -0.2,-1.1c-0.1,-0.4 -0.3,-0.7 -0.6,-1c-0.3,-0.3 -0.6,-0.5 -0.9,-0.6c-0.3,-0.2 -0.7,-0.3 -1.1,-0.3L32,41z"/>
<path android:fillColor="@android:color/white" android:pathData="M44.1,43l-0.5,0.1H43V47h-3.6V31.6H43c0.8,0 1.7,0.2 2.5,0.5c0.7,0.3 1.4,0.7 2,1.2c0.6,0.5 1,1.1 1.4,1.8c0.3,0.7 0.5,1.4 0.5,2.2c0,0.8 -0.2,1.6 -0.5,2.3c-0.4,0.7 -0.9,1.3 -1.5,1.8l3.4,5.5h-4.2L44.1,43zM43,39.5c0.4,0 0.7,-0.1 1.1,-0.2c0.3,-0.1 0.6,-0.3 0.9,-0.5c0.2,-0.2 0.5,-0.4 0.6,-0.7c0.1,-0.2 0.2,-0.5 0.2,-0.8c0,-0.3 -0.1,-0.6 -0.2,-0.8c-0.2,-0.3 -0.4,-0.5 -0.6,-0.7c-0.3,-0.2 -0.6,-0.4 -0.9,-0.5c-0.4,-0.1 -0.7,-0.2 -1.1,-0.2V39.5z"/>
</vector>

View file

@ -0,0 +1,17 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<group android:scaleX="0.67"
android:scaleY="0.67"
android:translateX="18"
android:translateY="18">
<path
android:pathData="M81.31,44.21h-0.82a1,1 0,0 1,-0.67 -1.64l0.56,-0.56a0.89,0.89 0,0 0,0 -1.28l-1.33,-1.34a0.91,0.91 0,0 0,-1.29 0L77.2,40a0.91,0.91 0,0 1,-1.55 -0.67v-0.82a0.92,0.92 0,0 0,-0.92 -0.92h-2a0.92,0.92 0,0 0,-0.92 0.92v0.82A1,1 0,0 1,70.3 40l-0.56,-0.57a0.91,0.91 0,0 0,-1.29 0l-1.34,1.34a0.89,0.89 0,0 0,0 1.28l0.47,0.46A1,1 0,0 1,67 44.21h-0.82a0.92,0.92 0,0 0,-0.93 0.93L65.25,47a0.92,0.92 0,0 0,0.93 0.93h0.77a1.06,1.06 0,0 1,0.72 1.74l-0.57,0.56a0.91,0.91 0,0 0,0 1.29l1.34,1.33a0.91,0.91 0,0 0,1.29 0l0.56,-0.56a1,1 0,0 1,1.65 0.66v0.77a0.92,0.92 0,0 0,0.92 0.92h1.8a0.92,0.92 0,0 0,0.93 -0.92v-0.77a1,1 0,0 1,1.65 -0.66l0.56,0.56a0.91,0.91 0,0 0,1.29 0l1.33,-1.33a0.91,0.91 0,0 0,0 -1.29l-0.46,-0.46A1.06,1.06 0,0 1,80.59 48h0.77a0.92,0.92 0,0 0,0.93 -0.93L82.29,45.19A1,1 0,0 0,81.31 44.21ZM73.7,49.21a3.08,3.08 0,1 1,3.08 -3.08A3.1,3.1 0,0 1,73.7 49.19Z"
android:fillColor="@android:color/white"/>
<path
android:pathData="M89.79,42.65c-0.5,-1.06 -2.7,-1.93 -6.52,-2.6a11.28,11.28 0,1 1,-18 -1.45c-3.33,-0.1 -7,-0.15 -11,-0.15C32,38.46 20.16,40 18.88,42.65c0,0 -1.31,2.34 -1.14,7.76H30.4a1,1 0,0 1,1.09 1c0,0.54 -0.68,1 -1.36,1H17.86c0.07,0.81 0.18,1.68 0.32,2.59h15a1,1 0,0 1,1.09 1c0,0.54 -0.68,1 -1.37,1H18.5c0.16,0.88 0.32,1.71 0.48,2.46H35.85a1,1 0,0 1,1.09 0.95c0,0.41 -0.68,1 -1.36,1H19.44c1.7,6.5 3.35,6.52 3.35,6.52H25v1.37c0,0.68 1.36,1.09 2.73,1.09H38.68c1.37,0 2.73,-0.55 2.73,-1.09V67.7H67.26v1.37c0,0.68 1.37,1.09 2.73,1.09H80.91c1.37,0 2.74,-0.55 2.74,-1.09V67.7h2.23s2.52,0 4.54,-12.25C91.91,46.39 89.79,42.65 89.79,42.65Z"
android:fillColor="@color/projectivy_plugin_color"/>
</group>
</vector>

View file

@ -0,0 +1,5 @@
<vector android:height="24dp"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M4,4h7L11,2L4,2c-1.1,0 -2,0.9 -2,2v7h2L4,4zM10,13l-4,5h12l-3,-4 -2.03,2.71L10,13zM17,8.5c0,-0.83 -0.67,-1.5 -1.5,-1.5S14,7.67 14,8.5s0.67,1.5 1.5,1.5S17,9.33 17,8.5zM20,2h-7v2h7v7h2L22,4c0,-1.1 -0.9,-2 -2,-2zM20,20h-7v2h7c1.1,0 2,-0.9 2,-2v-7h-2v7zM4,13L2,13v7c0,1.1 0.9,2 2,2h7v-2L4,20v-7z"/>
</vector>

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/projectivy_icon_background"/>
<foreground>
<inset android:drawable="@drawable/ic_banner_drawable" android:inset="18%"/>
</foreground>
</adaptive-icon>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/projectivy_icon_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
<monochrome android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View file

@ -0,0 +1 @@
{"v":"5.4.4","fr":29.9700012207031,"ip":0,"op":120.0000048877,"w":1920,"h":1080,"nm":"Gradient 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0],"e":[360]},{"t":119.000004846969}],"ix":10},"p":{"a":0,"k":[960,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":2,"s":{"a":0,"k":[2489,1768.076],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0,1,0.49,0.373,0.5,0.998,0.575,0.416,1,0.996,0.659,0.459],"ix":9}},"s":{"a":0,"k":[-411.974,-6.334],"ix":5},"e":{"a":0,"k":[352.025,-5.646],"ix":6},"t":1,"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-68,-34],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,184.116],"ix":3},"r":{"a":0,"k":89.879,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120.0000048877,"st":0,"bm":0}],"markers":[]}

Binary file not shown.

View file

@ -0,0 +1,8 @@
<resources>
<color name="projectivy_icon_background">#272525</color>
<color name="default_background">#3d3d3d</color>
<color name="app_background">#ff000000</color>
<color name="color_accent">#ffaa3f</color>
<color name="projectivy_color">#f08029</color>
<color name="projectivy_plugin_color">#904049</color>
</resources>

View file

@ -0,0 +1,10 @@
<resources>
<string name="plugin_name">Projectivy Wallpaper Provider Sample</string>
<string name="plugin_description">Plugin description</string>
<string name="plugin_uuid">CHANGE_ME</string>
<!-- Setting parameters -->
<string name="settings">Settings</string>
<string name="setting_image_url_title">Image URL</string>
</resources>

View file

@ -0,0 +1,16 @@
<resources>
<style name="Theme.ProjectivyWallpaperProvider" parent="@style/Theme.Leanback">
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:backgroundDimEnabled">false</item>
<item name="android:colorBackgroundCacheHint">@null</item>
<item name="android:windowActivityTransitions">true</item>
<item name="android:windowContentTransitions">true</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="colorPrimary">@color/app_background</item>
<item name="colorAccent">@color/color_accent</item>
</style>
</resources>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<integer name="items_cache_duration_millis">3600000</integer>
<integer name="update_mode_time_elapsed">1</integer>
<integer name="update_mode_now_playing_changed">2</integer>
<integer name="update_mode_card_focused">4</integer>
<integer name="update_mode_program_card_focused">8</integer>
<integer name="update_mode_launcher_idle_mode_changed">16</integer>
</resources>