├── screenshots ├── xml.png ├── app_1.jpg ├── app_2.jpg └── manifest.png ├── wallpaper.xml ├── AndroidManifest.xml ├── LICENSE ├── README.md └── WallpaperActivity.java /screenshots/xml.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PavelDoGreat/Unity-Android-Live-Wallpaper/HEAD/screenshots/xml.png -------------------------------------------------------------------------------- /screenshots/app_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PavelDoGreat/Unity-Android-Live-Wallpaper/HEAD/screenshots/app_1.jpg -------------------------------------------------------------------------------- /screenshots/app_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PavelDoGreat/Unity-Android-Live-Wallpaper/HEAD/screenshots/app_2.jpg -------------------------------------------------------------------------------- /screenshots/manifest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PavelDoGreat/Unity-Android-Live-Wallpaper/HEAD/screenshots/manifest.png -------------------------------------------------------------------------------- /wallpaper.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | -------------------------------------------------------------------------------- /AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Pavel Dobryakov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Unity Android Live Wallpaper 2 | 3 | Run your Unity game as live wallpaper on Android. Used in production by the app [*Fluid Simulation*](https://play.google.com/store/apps/details?id=games.paveldogreat.fluidsimfree). 4 | 5 | 6 | 7 | The main reason I open source it is because this implementation has several major bugs that I can't fix and I need help with: 8 | 9 | - When you launch lwp preview, press home button and then go back to preview. Whoops... it crashes. 10 | - On many launchers instead of fullscreen, it runs only in small portion of the screen. 11 | - Also not rendering in fullscreen when in landscape mode. 12 | 13 | So my goal is to fix these problems and to make this library the best Unity's lwp Android implementation ever, that is also the simplest and free. 14 | 15 | # Usage 16 | 17 | Export your game as Android Studio project. Then you need to make next steps: 18 | 19 | 1) Copy content from [AndroidManifest.xml](AndroidManifest.xml) to the project's AndroidManifest.xml, after main activity tag. Should look like this: 20 | 21 | 22 | 2) Add [WallpaperActivity.java](WallpaperActivity.java) script into the project. You probably would need to change the package name at the top of the script. 23 | 24 | 3) Make `xml` folder in `res` and add [wallpaper.xml](wallpaper.xml) file there. 25 | 26 | 27 | Now you can build and run. Go into wallpaper settings of your phone to see it. If you are using Samsung device then you need to install Google Wallpapers app to set it as a wallpaper. 28 | -------------------------------------------------------------------------------- /WallpaperActivity.java: -------------------------------------------------------------------------------- 1 | package change.packagename.here; 2 | 3 | import android.annotation.TargetApi; 4 | import android.app.WallpaperColors; 5 | import android.content.res.Configuration; 6 | import android.graphics.Color; 7 | import android.os.Build; 8 | import android.service.wallpaper.WallpaperService; 9 | import android.util.Log; 10 | import android.view.MotionEvent; 11 | import android.view.SurfaceHolder; 12 | import android.view.WindowInsets; 13 | import android.content.Context; 14 | 15 | import com.unity3d.player.UnityPlayer; 16 | 17 | class MyUnityPlayer extends UnityPlayer 18 | { 19 | public MyUnityPlayer (Context var) 20 | { 21 | super(var); 22 | } 23 | } 24 | 25 | public class WallpaperActivity extends WallpaperService 26 | { 27 | MyUnityPlayer mUnityPlayer; 28 | int mVisibleSurfaces = 0; 29 | 30 | @Override public void onCreate () 31 | { 32 | super.onCreate(); 33 | mUnityPlayer = new MyUnityPlayer(getApplicationContext()); 34 | } 35 | 36 | @Override public void onDestroy () 37 | { 38 | mUnityPlayer.quit(); 39 | super.onDestroy(); 40 | } 41 | 42 | @Override public Engine onCreateEngine () 43 | { 44 | return new MyEngine(); 45 | } 46 | 47 | @Override public void onLowMemory () 48 | { 49 | super.onLowMemory(); 50 | mUnityPlayer.lowMemory(); 51 | } 52 | 53 | @Override public void onTrimMemory(int level) 54 | { 55 | super.onTrimMemory(level); 56 | if (level == TRIM_MEMORY_RUNNING_CRITICAL) 57 | mUnityPlayer.lowMemory(); 58 | } 59 | 60 | @Override public void onConfigurationChanged (Configuration newConfig) 61 | { 62 | super.onConfigurationChanged(newConfig); 63 | mUnityPlayer.configurationChanged(newConfig); 64 | } 65 | 66 | void Log (String message) 67 | { 68 | Log.d("LiveWallpaper", message); 69 | } 70 | 71 | class MyEngine extends Engine 72 | { 73 | SurfaceHolder mHolder; 74 | boolean isPreview = false; 75 | 76 | @Override public void onCreate (SurfaceHolder holder) 77 | { 78 | Log("Create"); 79 | super.onCreate(holder); 80 | isPreview = isPreview(); 81 | setTouchEventsEnabled(true); 82 | setOffsetNotificationsEnabled(false); 83 | mUnityPlayer.UnitySendMessage("AppController", "TriggerIsWallpaper", isPreview ? "true" : "false"); 84 | } 85 | 86 | @Override public void onDestroy () 87 | { 88 | Log("Destroy"); 89 | super.onDestroy(); 90 | } 91 | 92 | @Override public void onApplyWindowInsets (WindowInsets insets) 93 | { 94 | super.onApplyWindowInsets(insets); 95 | int insetTop = 40; 96 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) 97 | insetTop = insets.getStableInsetTop(); 98 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) 99 | insetTop += 140; 100 | mUnityPlayer.UnitySendMessage("AppController", "ReceiveWindowInset", Integer.toString(insetTop)); 101 | } 102 | 103 | @TargetApi(Build.VERSION_CODES.O_MR1) 104 | @Override public WallpaperColors onComputeColors () 105 | { 106 | Color color = Color.valueOf(Color.BLACK); 107 | return new WallpaperColors(color, color, color); 108 | } 109 | 110 | @Override public void onSurfaceCreated (SurfaceHolder holder) 111 | { 112 | Log("SurfaceCreated"); 113 | super.onSurfaceCreated(holder); 114 | mHolder = holder; 115 | } 116 | 117 | @Override public void onSurfaceChanged (SurfaceHolder holder, int format, int width, int height) 118 | { 119 | Log("SurfaceChanged, width: " + width + ", height: " + height); 120 | super.onSurfaceChanged(holder, format, width, height); 121 | mHolder = holder; 122 | mUnityPlayer.displayChanged(0, mHolder.getSurface()); 123 | } 124 | 125 | @Override public void onVisibilityChanged (boolean visible) 126 | { 127 | Log("VisibilityChanged, isPreview: " + isPreview + ", visible: " + visible); 128 | super.onVisibilityChanged(visible); 129 | 130 | if (visible) 131 | { 132 | mVisibleSurfaces++; 133 | if (mHolder != null) 134 | mUnityPlayer.displayChanged(0, mHolder.getSurface()); 135 | mUnityPlayer.windowFocusChanged(true); 136 | mUnityPlayer.resume(); 137 | mUnityPlayer.UnitySendMessage("AppController", "TriggerVisible", isPreview ? "true" : "false"); 138 | return; 139 | } 140 | 141 | mVisibleSurfaces--; 142 | mVisibleSurfaces = Math.max(mVisibleSurfaces, 0); 143 | if (mVisibleSurfaces == 0) 144 | { 145 | mUnityPlayer.displayChanged(0, null); 146 | mUnityPlayer.windowFocusChanged(false); 147 | mUnityPlayer.pause(); 148 | } 149 | } 150 | 151 | @Override public void onSurfaceDestroyed (SurfaceHolder holder) 152 | { 153 | Log("SurfaceDestroyed"); 154 | super.onSurfaceDestroyed(holder); 155 | } 156 | 157 | @Override public void onTouchEvent (MotionEvent event) 158 | { 159 | super.onTouchEvent(event); 160 | mUnityPlayer.injectEvent(event); 161 | } 162 | } 163 | } --------------------------------------------------------------------------------